27 #include "code_generator.hpp"
28 #include "function_internal.hpp"
29 #include "convexify.hpp"
30 #include "blas_impl.hpp"
31 #include <casadi_runtime_str.h>
32 #include "global_options.hpp"
33 #include "filesystem_impl.hpp"
60 bool prefix_set =
false;
76 for (
auto&& e : opts) {
77 if (e.first==
"verbose") {
79 }
else if (e.first==
"verbose_runtime") {
81 }
else if (e.first==
"mex") {
83 }
else if (e.first==
"with_sfunction") {
85 }
else if (e.first==
"unroll_args") {
87 }
else if (e.first==
"static_aux") {
89 }
else if (e.first==
"inline_aux") {
91 }
else if (e.first==
"cpp") {
93 }
else if (e.first==
"main") {
94 this->
main = e.second;
95 }
else if (e.first==
"casadi_real") {
97 }
else if (e.first==
"casadi_int") {
99 }
else if (e.first==
"codegen_scalars") {
101 }
else if (e.first==
"with_header") {
103 }
else if (e.first==
"with_mem") {
105 }
else if (e.first==
"with_export") {
107 }
else if (e.first==
"with_import") {
109 }
else if (e.first==
"include_math") {
111 }
else if (e.first==
"infinity") {
112 this->
infinity = e.second.to_string();
113 }
else if (e.first==
"nan") {
114 this->
nan = e.second.to_string();
115 }
else if (e.first==
"real_min") {
116 this->
real_min = e.second.to_string();
117 }
else if (e.first==
"indent") {
120 }
else if (e.first==
"avoid_stack") {
122 }
else if (e.first==
"prefix") {
123 this->
prefix = e.second.to_string();
125 }
else if (e.first==
"dump_dir_prefix") {
127 }
else if (e.first==
"dump_dir_suffix") {
129 }
else if (e.first==
"max_declarations_per_line") {
132 "Option max_declarations_per_line must be >=0");
133 }
else if (e.first==
"max_initializer_elements_per_line") {
136 "Option max_initializer_elements_per_line must be >=0");
137 }
else if (e.first==
"force_canonical") {
139 }
else if (e.first==
"l1_blas") {
141 }
else if (e.first==
"thread_safe") {
144 casadi_error(
"Unrecognized option: " +
str(e.first));
149 casadi_error(
"Codegen options 'with_mem' and 'force_canonical=false' (the default) "
150 "are incompatible. If you rely on with_mem, please explicitly set force_canonical=true.");
155 std::stringstream ss;
156 ss << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1);
158 ss << std::numeric_limits<float>::min();
161 ss << std::numeric_limits<double>::min();
178 std::string::size_type dotpos =
name.rfind(
'.');
179 if (dotpos==std::string::npos) {
181 this->
suffix = this->
cpp ?
".cpp" :
".c";
183 this->name =
name.substr(0, dotpos);
184 this->
suffix = name.substr(dotpos);
219 this->
header <<
"#include <casadi/mem.h>\n";
239 *
this <<
"return " << value <<
";\n";
243 *
this <<
"ret = " << value <<
";\n";
249 *
this <<
"return;\n";
262 std::map<std::string, std::set<std::pair<std::string, std::string>>> local_variables_by_type;
264 local_variables_by_type[e.second.first].insert(std::make_pair(e.first, e.second.second));
268 for (
auto&& e : local_variables_by_type) {
270 for (
auto it=e.second.begin(); it!=e.second.end(); ++it) {
271 bool split_declaration = it==e.second.begin() ||
273 if (split_declaration) {
274 if (it!=e.second.begin())
body <<
";\n";
275 body <<
" " << e.first <<
" ";
279 body << it->second << it->first;
295 *
this <<
"return;\n";
297 *
this <<
"return ret;\n";
305 auto it = funs.find(f);
306 if (it==funs.end()) {
307 casadi_int n = funs.size();
338 *
this <<
"int " << fname <<
"_alloc_mem(void) {\n";
346 *
this <<
"int " << fname <<
"_init_mem(int mem) {\n";
354 *
this <<
"void " << fname <<
"_free_mem(int mem) {\n";
363 *
this <<
"int " << fname <<
"_checkout(void) {\n";
371 *
this <<
"void " << fname <<
"_release(int mem) {\n";
383 *
this <<
"void " << fname <<
"_incref(void) {\n";
388 *
this <<
"void " << fname <<
"_decref(void) {\n";
403 "Cannot code generate '" + f.
name() +
"': name conflicts with an external dependency.");
407 <<
"return " << codegen_name <<
"(arg, res, iw, w, mem);\n"
413 for (casadi_int i=0; i<f.
n_in(); ++i) {
414 *
this <<
"arg[" << i <<
"] = " << f.
name_in(i) <<
";\n";
416 for (casadi_int i=0; i<f.
n_out(); ++i) {
417 *
this <<
"res[" << i <<
"] = " << f.
name_out(i) <<
";\n";
419 *
this <<
"return " << codegen_name <<
"(arg, res, iw, w, mem);\n";
429 if (with_jac_sparsity) {
453 std::stringstream ss;
454 ss << CASADI_MAJOR_VERSION <<
"." << CASADI_MINOR_VERSION <<
"." << CASADI_PATCH_VERSION;
455 if (!CASADI_IS_RELEASE) ss <<
"+";
462 f <<
"/* This file was automatically generated by CasADi " <<
casadi_version() <<
".\n"
463 <<
" * It consists of: \n"
464 <<
" * 1) content generated by CasADi runtime: not copyrighted\n"
465 <<
" * 2) template code copied from CasADi source: permissively licensed (MIT-0)\n"
466 <<
" * 3) user code: owned by the user\n"
472 f <<
"#ifdef __cplusplus\n"
473 <<
"extern \"C\" {\n"
481 f <<
"#ifdef __cplusplus\n"
482 <<
"} /* extern \"C\" */\n"
487 void CodeGenerator::generate_casadi_real(std::ostream &s)
const {
488 s <<
"#ifndef casadi_real\n"
493 void CodeGenerator::generate_export_symbol(std::ostream &s)
const {
494 s <<
"/* Symbol visibility in DLLs */\n"
495 <<
"#ifndef CASADI_SYMBOL_EXPORT\n"
496 <<
" #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)\n"
497 <<
" #if defined(STATIC_LINKED)\n"
498 <<
" #define CASADI_SYMBOL_EXPORT\n"
500 <<
" #define CASADI_SYMBOL_EXPORT __declspec(dllexport)\n"
502 <<
" #elif defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)\n"
503 <<
" #define CASADI_SYMBOL_EXPORT __attribute__ ((visibility (\"default\")))\n"
504 <<
" #else" << std::endl
505 <<
" #define CASADI_SYMBOL_EXPORT\n"
510 void CodeGenerator::generate_import_symbol(std::ostream &s)
const {
511 s <<
"/* Symbol visibility in DLLs */\n"
512 <<
"#ifndef CASADI_SYMBOL_IMPORT\n"
513 <<
" #if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)\n"
514 <<
" #if defined(STATIC_LINKED)\n"
515 <<
" #define CASADI_SYMBOL_IMPORT\n"
517 <<
" #define CASADI_SYMBOL_IMPORT __declspec(dllimport)\n"
519 <<
" #elif defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)\n"
520 <<
" #define CASADI_SYMBOL_IMPORT __attribute__ ((visibility (\"default\")))\n"
521 <<
" #else" << std::endl
522 <<
" #define CASADI_SYMBOL_IMPORT\n"
527 void CodeGenerator::generate_casadi_int(std::ostream &s)
const {
528 s <<
"#ifndef casadi_int\n"
536 casadi_assert(
prefix.find(this->name + this->suffix)==std::string::npos,
537 "The signature of CodeGenerator::generate has changed. "
538 "Instead of providing the filename, only provide the prefix.");
544 std::ostream& s = *s_ptr;
551 s <<
"CASADI_SYMBOL_EXPORT casadi_real* CASADI_PREFIX(get_pool_double)(const char* name) {\n";
553 casadi_int i = e.second;
554 s <<
" if (strcmp(name, \"" + e.first +
"\")==0) "
555 <<
"return casadi_pd" +
str(i) +
";\n";
562 if (this->
mex) generate_mex(s);
565 if (this->
main) generate_main(s);
576 generate_sfunction(sfunction_name, sfunction_code);
583 std::ostream& s = *s_ptr;
588 generate_casadi_real(s);
591 generate_casadi_int(s);
606 void CodeGenerator::generate_mex(std::ostream &s)
const {
608 s <<
"#ifdef MATLAB_MEX_FILE\n";
611 if (this->
cpp) s <<
"extern \"C\"\n";
612 s <<
"void mexFunction(int resc, mxArray *resv[], int argc, const mxArray *argv[]) {"
620 s <<
" char buf[" << (buf_len+1) <<
"];\n";
623 s <<
" int buf_ok = argc > 0 && !mxGetString(*argv, buf, sizeof(buf));\n";
626 s <<
" if (!buf_ok) {\n";
629 s <<
" mex_" <<
exposed_fname[0] <<
"(resc, resv, argc, argv);\n"
632 s <<
" /* name error */\n";
635 s <<
" } else if (strcmp(buf, \"" <<
exposed_fname[i] <<
"\")==0) {\n"
636 <<
" mex_" <<
exposed_fname[i] <<
"(resc, resv, argc-1, argv+1);\n"
642 s <<
" mexErrMsgTxt(\"First input should be a command string. Possible values:";
653 void CodeGenerator::generate_sfunction(
const std::string& name,
654 const std::string& sfunction)
const {
657 std::ostream& f = *f_ptr;
660 f <<
"// Must specify the S_FUNCTION_NAME as the name of the S-function\n"
661 <<
"#define S_FUNCTION_NAME sfun_" <<
name <<
"\n"
662 <<
"#define S_FUNCTION_LEVEL 2\n\n"
663 <<
"// Need to include simstruc.h for the definition of the SimStruct and its\n"
664 <<
"// associated macro definitions\n"
665 <<
"#ifndef __SIMSTRUC__\n"
666 <<
"#include \"simstruc.h\"\n"
668 <<
"// Specific header file(s) required by the legacy code function\n"
669 <<
"#include \"" << this->name <<
".h\"\n\n\n";
676 std::string CodeGenerator::codegen_sfunction(
const Function& f)
const {
682 g <<
"/* Function: mdlInitializeSizes ===========================================\n"
684 <<
"* The sizes information is used by Simulink to determine the S-function\n"
685 <<
"* blocks characteristics (number of inputs, outputs, states, etc.).\n"
687 <<
"static void mdlInitializeSizes(SimStruct *S)\n"
689 <<
" /* Declare auxilary variables */\n"
691 <<
" const int_T* sp;\n\n"
692 <<
" /* Set number of simulink s-function block parameters "
693 "(the ones which appear by double click on simulink block) */\n"
694 <<
" ssSetNumSFcnParams(S, 0);\n\n"
695 <<
" /* Report if parameter mismatch occurs */\n"
696 <<
" if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;\n\n"
697 <<
" /* Specify the number of states for which a block detects "
698 "zero crossings that occur between sample points */\n"
699 <<
" ssSetNumNonsampledZCs(S, 0);\n\n"
700 <<
" /* Set number of simulink input ports */\n"
701 <<
" if (!ssSetNumInputPorts(S, " << f->n_in_ <<
")) return;\n\n"
702 <<
" /* Configure simulink input ports (inputs are assumed to be dense "
703 "vectors or matrices) */\n"
704 <<
" for (ii=0; ii<" << f->n_in_ <<
"; ++ii) {\n"
705 <<
" sp = " << f.name() <<
"_sparsity_in(ii);\n"
706 <<
" if (sp[1]==1) {\n"
707 <<
" ssSetInputPortWidth(S, ii, sp[0]);\n"
710 <<
" ssSetInputPortMatrixDimensions(S, ii, sp[0], sp[1]);\n"
712 <<
" ssSetInputPortDirectFeedThrough(S, ii, 1);\n"
714 <<
" /* Set number of simulink output ports */\n"
715 <<
" if (!ssSetNumOutputPorts(S, " << f->n_out_ <<
")) return;\n\n"
716 <<
" /* Configure simulink output ports (dense or sparse vectors or matrices allowed) */\n"
717 <<
" for (ii=0; ii<" << f->n_out_ <<
"; ++ii) {\n"
718 <<
" sp = " << f.name() <<
"_sparsity_out(ii);\n"
719 <<
" if (sp[1]==1) {\n"
720 <<
" ssSetOutputPortWidth(S, ii, sp[0]);\n"
723 <<
" ssSetOutputPortMatrixDimensions(S, ii, sp[0], sp[1]);\n"
726 <<
" ssSetOutputPortOutputExprInRTW(S, 0, 0);\n\n"
727 <<
" /* This S-function can be used in referenced model simulating in normal mode */\n"
728 <<
" ssSetModelReferenceNormalModeSupport(S, MDL_START_AND_MDL_PROCESS_PARAMS_OK);\n\n"
729 <<
" /* Set the number of sample time */\n"
730 <<
" ssSetNumSampleTimes(S, 1);\n\n"
731 <<
" /* Set the compliance with the SimState feature */\n"
732 <<
" ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);\n\n"
734 <<
" * All options have the form SS_OPTION_<name> and are documented in\n"
735 <<
" * matlabroot/simulink/include/simstruc.h. The options should be\n"
736 <<
" * bitwise ord together as in\n"
737 <<
" * ssSetOptions(S, (SS_OPTION_name1 | SS_OPTION_name2))\n"
742 g <<
"/* Function: mdlInitializeSampleTimes =====================================\n"
744 <<
" * This function is used to specify the sample time(s) for your\n"
745 <<
" * S-function. You must register the same number of sample times as\n"
746 <<
" * specified in ssSetNumSampleTimes.\n"
748 <<
"static void mdlInitializeSampleTimes(SimStruct *S)\n"
750 <<
" ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);\n"
751 <<
" ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET);\n"
752 <<
" #if defined(ssSetModelReferenceSampleTimeDefaultInheritance)\n"
753 <<
" ssSetModelReferenceSampleTimeDefaultInheritance(S);\n"
758 g <<
"/* Function: mdlOutputs ===================================================\n"
760 <<
" * In this function, you compute the outputs of your S-function\n"
761 <<
" * block. Generally outputs are placed in the output vector(s),\n"
762 <<
" * ssGetOutputPortSignal.\n"
764 <<
"static void mdlOutputs(SimStruct *S, int_T tid)\n"
766 <<
" /* Declare auxilary variables */\n"
767 <<
" int_T ii, jj, row, col, nnz_col, ind_start_row_index, offset = 0, jj_total = 0;\n"
768 <<
" const int_T* sp;\n\n"
769 <<
" /* Allocate buffers for casadi input and output and simulink output */\n"
770 <<
" " +
array(
"real_T",
"w", f->sz_w()+f->nnz_out())
771 <<
" " +
array(
"int_T",
"iw", f->sz_iw())
772 <<
" const real_T* arg[" << f->sz_arg() <<
"] = {0};\n"
773 <<
" real_T* res[" << f->sz_res() <<
"] = {0};\n"
774 <<
" real_T* y[" << f->n_out_ <<
"] = {0};\n\n"
775 <<
" /* Point inputs directly to casadi input buffer */\n"
776 <<
" for (ii=0; ii<" << f->n_in_ <<
";++ii) {\n"
777 <<
" arg[ii] = *ssGetInputPortRealSignalPtrs( S, ii );\n"
779 <<
" /* Point outputs to buffer */\n"
780 <<
" for (ii=0; ii<" << f->n_out_ <<
";++ii) {\n"
781 <<
" y[ii] = ssGetOutputPortRealSignal( S, ii );\n"
783 <<
" /* Point allocated working array to casadi output buffer */\n";
784 for (casadi_int ii=0; ii<f->n_out_; ++ii) {
785 g <<
" res[" << ii <<
"] = w + offset;\n"
786 <<
" offset += " << f.nnz_out(ii) <<
";\n";
789 <<
" /* Call CasADi function */\n"
790 <<
" " << f.name() <<
"( arg, res, iw, w+offset, 0 );\n\n"
791 <<
" /* Assign results to Simulink output array */\n"
792 <<
" for (ii=0; ii<" << f->n_out_ <<
"; ++ii){\n\n"
793 <<
" /* Get sparsity information of casadi function output "
794 "(sp[0] - n_rows, sp[1] - n_cols, sp[2] - dense/sparse) */\n"
795 <<
" sp = " << f.name() <<
"_sparsity_out(ii);\n\n"
796 <<
" /* Check if output is dense (sp[2]=1) or sparse (sp[2]=0) */\n"
797 <<
" if (sp[2]==0) {\n"
798 <<
" jj_total = 0;\n"
799 <<
" ind_start_row_index = 2 + sp[1] + 1;\n\n"
800 <<
" /* Distribute nonzero elements column by column */\n"
801 <<
" for (col=0; col<sp[1]; col++) {\n\n"
802 <<
" /* The cumulative sum of nonzero elements after each column starts at index 2, "
803 "after last entry of CCS array col_ptr; number of nonzero elements in current column is "
804 "obtained by the difference of two consecutive values */\n"
805 <<
" nnz_col = sp[2+col+1] - sp[2+col];\n\n"
806 <<
" /* Distribute nonzero elements of current column to correct row position */\n"
807 <<
" for (jj=0; jj<nnz_col; jj++) {\n"
808 <<
" row = sp[ind_start_row_index+jj_total];\n"
809 <<
" y[ii][row + sp[0]*col] = res[ii][jj_total];\n"
815 <<
" y[ii] = res[ii];\n"
821 g <<
"/* Function: mdlTerminate =================================================\n"
823 <<
" * In this function, you should perform any actions that are necessary\n"
824 <<
" * at the termination of a simulation.\n"
826 <<
"static void mdlTerminate(SimStruct *S)\n"
829 <<
"/* Required S-function trailer */\n"
830 <<
"#ifdef MATLAB_MEX_FILE\n"
831 <<
"# include \"simulink.c\"\n"
833 <<
"# include \"cg_sfun.h\"\n"
839 void CodeGenerator::generate_main(std::ostream &s)
const {
840 s << this->
dll_export <<
"int main(int argc, char* argv[]) {\n";
843 s <<
" if (argc<2) {\n"
844 <<
" /* name error */\n";
846 s <<
" } else if (strcmp(argv[1], \"" <<
exposed_fname[i] <<
"\")==0) {\n"
847 <<
" return main_" <<
exposed_fname[i] <<
"(argc-2, argv+2);\n";
852 s <<
" fprintf(stderr, \"First input should be a command string. Possible values:";
857 s <<
"Note: you may use function.generate_input to create a command string.";
876 return "casadi_rd" +
str(size);
890 return "casadi_ri" +
str(size);
908 return "casadi_pd" +
str(it->second);
912 const std::string& name) {
916 auxiliaries <<
"#if CASADI_MUTEX_USE_STATIC_INIT == 0\n";
917 auxiliaries <<
"static CASADI_MUTEX_TYPE " << sh <<
";\n";
920 <<
" = CASADI_MUTEX_STATIC_INIT;\n";
925 const std::string& name)
const {
928 "Mutex not defined: " +
name);
946 s <<
"/* How to prefix internal symbols */\n"
947 <<
"#ifdef CASADI_CODEGEN_PREFIX\n"
948 <<
" #define CASADI_NAMESPACE_CONCAT(NS, ID) _CASADI_NAMESPACE_CONCAT(NS, ID)\n"
949 <<
" #define _CASADI_NAMESPACE_CONCAT(NS, ID) NS ## ID\n"
950 <<
" #define CASADI_PREFIX(ID) CASADI_NAMESPACE_CONCAT(CODEGEN_PREFIX, ID)\n"
952 <<
" #define CASADI_PREFIX(ID) " << this->
prefix <<
"_ ## ID\n"
960 generate_casadi_real(s);
963 generate_casadi_int(s);
966 s <<
"#ifndef CASADI_MAX_NUM_THREADS\n";
967 s <<
"#define CASADI_MAX_NUM_THREADS 1\n";
974 s <<
"#include <casadi/mem.h>\n" << std::endl;
979 s <<
"/* Add prefix to internal symbols */\n";
981 s <<
"#define " <<
"casadi_" << i <<
" CASADI_PREFIX(" << i <<
")\n";
1032 std::vector<double> sz_zeros(
sz_zeros_, 0);
1033 print_vector(s,
"casadi_zeros", std::vector<double>(sz_zeros));
1038 std::vector<double> sz_ones(
sz_ones_, 0);
1039 print_vector(s,
"casadi_ones", std::vector<double>(sz_ones));
1047 s <<
"static casadi_real casadi_rd" +
str(i++) +
"[" +
str(it.second) +
"];\n";
1056 s <<
"static casadi_real casadi_ri" +
str(i++) +
"[" +
str(it.second) +
"];\n";
1065 s <<
"casadi_real casadi_pd" +
str(i) +
1074 s <<
"/* External functions */\n";
1076 s << i << std::endl;
1078 s << std::endl << std::endl;
1082 s << this->
body.str();
1102 if (n<0)
return "0";
1103 std::stringstream s;
1130 std::stringstream ss;
1137 const std::string& def) {
1138 std::stringstream s;
1141 s <<
"*" <<
name <<
" = 0";
1143 s <<
name <<
"[" << len <<
"]";
1144 if (!def.empty()) s <<
" = " << def;
1151 const std::vector<casadi_int>& v) {
1156 const std::vector<char>& v) {
1161 const std::vector<double>& v) {
1166 const std::vector<std::string>& v) {
1172 std::stringstream s;
1173 s <<
"casadi_print_canonical(" <<
sparsity(sp) <<
", " <<
arg <<
");";
1179 std::stringstream s;
1180 s <<
"casadi_print_vector(" << sz <<
", " <<
arg <<
");";
1186 std::stringstream s;
1187 s <<
"casadi_print_scalar(" <<
arg <<
");";
1193 std::stringstream s;
1194 s <<
"casadi_fprintf_scalar(" << f <<
", " <<
arg <<
");";
1199 const std::string& arg,
const std::string& sep) {
1201 std::stringstream s;
1202 s <<
"casadi_fprintf_vector(" << f <<
", " << sz <<
", " <<
arg <<
", \"" << sep <<
"\");";
1210 return "casadi_fabs("+a0+
")";
1213 return "casadi_sq("+a0+
")";
1216 return "casadi_sign("+a0+
")";
1219 return "casadi_log1p("+a0+
")";
1222 return "casadi_expm1("+a0+
")";
1231 return "casadi_fmin("+a0+
","+a1+
")";
1234 return "casadi_fmax("+a0+
","+a1+
")";
1237 return "casadi_hypot("+a0+
","+a1+
")";
1240 return "casadi_printme("+a0+
","+a1+
")";
1247 const std::string& use_ifdef) {
1255 if (!use_ifdef.empty()) this->
includes <<
"#ifdef " << use_ifdef << std::endl;
1258 if (relative_path) {
1259 this->
includes <<
"#include \"" << new_include <<
"\"\n";
1261 this->
includes <<
"#include <" << new_include <<
">\n";
1265 if (!use_ifdef.empty()) this->
includes <<
"#endif\n";
1272 *
this << s <<
".checkout = " <<
name <<
"_checkout;\n";
1274 *
this << s <<
".checkout = 0;\n";
1277 *
this << s <<
".eval = " <<
name <<
";\n";
1279 *
this << s <<
".release = " <<
name <<
"_release;\n";
1281 *
this << s <<
".release = 0;\n";
1287 const std::string& res,
const std::string& iw,
1288 const std::string& w,
const std::string& failure_ret) {
1294 std::string
mem =
"mid";
1295 local(
"flag",
"int");
1297 std::string checkout =
shorthand(cg_name +
"_checkout");
1298 *
this <<
mem <<
" = " << checkout <<
"();\n";
1299 if (failure_ret.empty()) {
1300 *
this <<
"if (" <<
mem <<
"<0) {\n";
1301 *
this <<
"flag = 1;\n";
1302 *
this <<
"} else {\n";
1304 *
this <<
"if (" <<
mem <<
"<0) return " << failure_ret <<
";\n";
1307 *
this <<
"flag = " +
name +
"(" +
arg +
", " +
res +
", "
1308 + iw +
", " + w +
", " <<
mem <<
");\n";
1310 if (failure_ret.empty()) {
1314 std::string release =
shorthand(cg_name +
"_release");
1315 *
this << release <<
"(" <<
mem <<
");\n";
1319 + iw +
", " + w +
", 0)";
1324 if (!
name.empty()) {
1327 "Cannot code generate '" +
name +
"': name conflicts with an external dependency.");
1335 return "casadi_" +
name;
1340 if (!allow_adding) {
1341 casadi_assert(added,
"Duplicate macro: " +
name);
1343 return "casadi_" +
name;
1362 casadi_assert_dev(
sizeof(
double) %
sizeof(
size_t)==0);
1363 const casadi_int int_len = v.size()*(
sizeof(double)/
sizeof(
size_t));
1364 const size_t* int_v =
reinterpret_cast<const size_t*
>(&v.front());
1365 for (
size_t i=0; i<int_len; ++i) {
1396 for (
auto i=eq.first; i!=eq.second; ++i) {
1407 casadi_error(
"Constant not found");
1417 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1419 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1430 casadi_error(
"Constant not found");
1440 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1442 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1453 casadi_error(
"Constant not found");
1463 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1465 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1476 casadi_error(
"Constant not found");
1504 const std::string& name,
const std::vector<casadi_int>& v,
const std::string& type) {
1513 (*this) <<
"for (i=0;i<" << v.size() <<
";++i) " +
name +
"[i] = " + ref +
"[i];\n";
1527 for (
auto it=f_match.first; it!=f_match.second; ++it) {
1528 if (it->second==inst)
return;
1719 std::vector<std::string> inst2 = inst;
1720 if (inst.size()==1) inst2.push_back(inst[0]);
1727 std::vector<std::string> inst2 = inst;
1728 if (inst.size()==1) inst2.push_back(inst[0]);
1908 this->
auxiliaries <<
"#define casadi_to_double(x) "
1909 <<
"(" << (this->
cpp ?
"static_cast<double>(x)" :
"(double) x") <<
")\n\n";
1913 <<
"(" << (this->
cpp ?
"static_cast<casadi_int>(x)" :
"(casadi_int) x")
1918 <<
"(" << (this->
cpp ?
"static_cast<x>(y)" :
"(x) y") <<
")\n\n";
1922 "// SYMBOL \"sq\"\n"
1923 "casadi_real casadi_sq(casadi_real x) { return x*x;}\n\n",
1928 "// SYMBOL \"sign\"\n"
1929 "casadi_real casadi_sign(casadi_real x) "
1930 "{ return x<0 ? -1 : x>0 ? 1 : x;}\n\n",
1935 "// SYMBOL \"if_else\"\n"
1936 "casadi_real casadi_if_else"
1937 "(casadi_real c, casadi_real x, casadi_real y) "
1938 "{ return c!=0 ? x : y;}\n\n",
1945 <<
" #define CASADI_PRINTF mexPrintf\n"
1947 <<
" #define CASADI_PRINTF printf\n"
1951 this->
auxiliaries <<
"#define CASADI_PRINTF printf\n";
1953 this->
auxiliaries <<
"#define CASADI_SNPRINTF snprintf\n";
1960 "// SYMBOL \"fmin\"\n"
1961 "casadi_real casadi_fmin(casadi_real x, casadi_real y) {\n"
1962 "/* Pre-c99 compatibility */\n"
1963 "#if __STDC_VERSION__ < 199901L\n"
1964 " return x<y ? x : y;\n"
1966 " return fmin(x, y);\n"
1973 "// SYMBOL \"fmax\"\n"
1974 "casadi_real casadi_fmax(casadi_real x, casadi_real y) {\n"
1975 "/* Pre-c99 compatibility */\n"
1976 "#if __STDC_VERSION__ < 199901L\n"
1977 " return x>y ? x : y;\n"
1979 " return fmax(x, y);\n"
1986 "// SYMBOL \"fabs\"\n"
1987 "casadi_real casadi_fabs(casadi_real x) {\n"
1988 "/* Pre-c99 compatibility */\n"
1989 "#if __STDC_VERSION__ < 199901L\n"
1990 " return x>0 ? x : -x;\n"
1992 " return fabs(x);\n"
1999 "// SYMBOL \"isinf\"\n"
2000 "casadi_real casadi_isinf(casadi_real x) {\n"
2001 "/* Pre-c99 compatibility */\n"
2002 "#if __STDC_VERSION__ < 199901L\n"
2003 " return x== INFINITY || x==-INFINITY;\n"
2005 " return isinf(x);\n"
2012 "// SYMBOL \"isfinite\"\n"
2013 "casadi_real casadi_isfinite(casadi_real x) {\n"
2014 "/* Pre-c99 compatibility */\n"
2015 "#if __STDC_VERSION__ < 199901L\n"
2016 " return x==x && x!=INFINITY && x!=-INFINITY;\n"
2018 " return isfinite(x);\n"
2025 "// SYMBOL \"min\"\n"
2026 "casadi_int casadi_min(casadi_int x, casadi_int y) {\n"
2027 " return x>y ? y : x;\n"
2033 "// SYMBOL \"max\"\n"
2034 "casadi_int casadi_max(casadi_int x, casadi_int y) {\n"
2035 " return x>y ? x : y;\n"
2051 <<
" #define casadi_inf " << this->
infinity <<
"\n"
2056 <<
" #define casadi_nan " << this->
nan <<
"\n"
2061 <<
" #define casadi_real_min " << this->
real_min <<
"\n"
2066 "// SYMBOL \"log1p\"\n"
2067 "casadi_real casadi_log1p(casadi_real x) {\n"
2068 "/* Pre-c99 compatibility */\n"
2069 "#if __STDC_VERSION__ < 199901L\n"
2070 " return log(1+x);\n"
2072 " return log1p(x);\n"
2079 "// SYMBOL \"expm1\"\n"
2080 "casadi_real casadi_expm1(casadi_real x) {\n"
2081 "/* Pre-c99 compatibility */\n"
2082 "#if __STDC_VERSION__ < 199901L\n"
2083 " return exp(x)-1;\n"
2085 " return expm1(x);\n"
2092 "// SYMBOL \"hypot\"\n"
2093 "casadi_real casadi_hypot(casadi_real x, casadi_real y) {\n"
2094 "/* Pre-c99 compatibility */\n"
2095 "#if __STDC_VERSION__ < 199901L\n"
2096 " return sqrt(x*x+y*y);\n"
2098 " return hypot(x, y);\n"
2167 std::stringstream s;
2168 s <<
"casadi_to_mex(" <<
sparsity(sp) <<
", " <<
arg <<
");";
2173 const std::string& res, std::size_t res_off,
2174 const Sparsity& sp_res,
const std::string& w) {
2179 std::stringstream s;
2180 s <<
"casadi_from_mex(" <<
arg
2181 <<
", " <<
res <<
", " <<
sparsity(sp_res) <<
", " << w <<
");";
2187 std::stringstream ret;
2189 std::istringstream stream(casadi_fmu_str);
2190 while (std::getline(stream, line)) {
2192 if (line.find(
"MODELNAME") != std::string::npos) {
2193 line =
replace(line,
"MODELNAME", modelname);
2196 ret << line <<
"\n";
2202 std::string ret = v;
2203 ret =
replace(ret,
"\\",
"\\\\");
2204 ret =
replace(ret,
"\"",
"\\\"");
2205 return "\"" + ret +
"\"";
2213 return constant(
static_cast<casadi_int
>(v));
2216 std::stringstream s;
2220 }
else if (isinf(v)) {
2225 casadi_int v_int =
static_cast<casadi_int
>(v);
2226 if (
static_cast<double>(v_int)==v) {
2231 std::ios_base::fmtflags fmtfl = s.flags();
2232 s << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1) << v;
2240 std::size_t n,
const std::string& res) {
2241 std::stringstream s;
2244 s <<
"casadi_copy(" <<
arg <<
", " << n <<
", " <<
res <<
");";
2254 bool check_lhs,
bool check_rhs) {
2255 std::vector<std::string> checks;
2256 if (check_lhs) checks.push_back(
arg);
2257 if (check_rhs) checks.push_back(
res);
2258 if (!checks.empty()) *
this <<
"if (" <<
join(checks,
" && ") <<
") ";
2263 const std::string& def,
bool check_rhs) {
2264 *
this <<
"if (" <<
arg <<
") {\n";
2265 if (check_rhs) *
this <<
"if (" <<
res <<
") ";
2267 *
this <<
"} else {\n";
2268 if (check_rhs) *
this <<
"if (" <<
res <<
") ";
2269 *
this <<
fill(
res, n, def) <<
"\n";
2274 std::stringstream s;
2277 s <<
"casadi_clear(" <<
res <<
", " << n <<
");";
2282 return "arg[" +
str(i) +
"]";
2286 return "res[" +
str(i) +
"]";
2292 return mem_array+
"[mem]";
2296 std::size_t n,
const std::string& v) {
2298 std::stringstream s;
2301 s <<
"casadi_fill(" <<
res <<
", " << n <<
", " << v <<
");";
2306 const std::string& y) {
2308 std::stringstream s;
2309 s <<
"casadi_dot(" << n <<
", " << x <<
", " << y <<
")";
2314 const std::string& x,
const std::string& y) {
2316 std::stringstream s;
2317 s <<
"casadi_bilin(" << A <<
", " <<
sparsity(sp_A) <<
", " << x <<
", " << y <<
")";
2322 const std::string& alpha,
const std::string& x,
2323 const std::string& y) {
2325 std::stringstream s;
2326 s <<
"casadi_rank1(" << A <<
", " <<
sparsity(sp_A) <<
", "
2327 << alpha <<
", " << x <<
", " << y <<
");";
2332 const std::string& res, casadi_int ndim,
const std::string& grid,
2333 const std::string& offset,
2334 const std::string& values,
const std::string& x,
2335 const std::string& lookup_mode, casadi_int m,
2336 const std::string& iw,
const std::string& w) {
2338 std::stringstream s;
2339 s <<
"casadi_interpn(" <<
res <<
", " << ndim <<
", " << grid <<
", " << offset <<
", "
2340 << values <<
", " << x <<
", " << lookup_mode <<
", " << m <<
", " << iw <<
", " << w <<
");";
2345 casadi_int ndim,
const std::string& grid,
const std::string& offset,
2346 const std::string& values,
const std::string& x,
2347 const std::string& lookup_mode, casadi_int m,
2348 const std::string& iw,
const std::string& w) {
2350 std::stringstream s;
2351 s <<
"casadi_interpn_grad(" << grad <<
", " << ndim <<
", " << grid <<
", " << offset <<
", "
2352 << values <<
", " << x <<
", " << lookup_mode <<
"," << m <<
", " << iw <<
", " << w <<
");";
2357 const std::string& y,
const Sparsity& sp_y,
2358 const std::string& iw) {
2360 return "casadi_trans(" + x +
"," +
sparsity(sp_x) +
", "
2361 + y +
", " +
sparsity(sp_y) +
", " + iw +
")";
2366 std::string cpp_prefix = this->
cpp ?
"extern \"C\" " :
"";
2374 return cpp_prefix + this->dll_export + s;
2379 const std::string& res,
const Sparsity& sp_res,
2380 const std::string& w) {
2386 std::stringstream s;
2387 s <<
"casadi_project(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", " <<
res <<
", "
2388 <<
sparsity(sp_res) <<
", " << w <<
");";
2394 const std::string& res,
bool lower) {
2397 std::stringstream s;
2398 s <<
"casadi_tri_project(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", ";
2399 s <<
res <<
", " << (lower ? 1: 0) <<
");";
2405 const std::string& res,
bool tr) {
2408 std::stringstream s;
2409 s <<
"casadi_densify(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", " <<
res <<
", "
2410 << (tr ? 1 : 0) <<
");";
2419 std::stringstream s;
2420 s <<
"casadi_sparsify(" <<
arg <<
", " <<
res <<
", "
2421 <<
sparsity(sp_res) <<
", " << (tr ? 1 : 0) <<
");";
2427 std::stringstream s;
2428 s <<
"CASADI_PRINTF(";
2430 std::string::size_type pos = 0, prev = 0;
2431 while ((pos =
str.find(
'\n', prev)) != std::string::npos) {
2433 s <<
"\"" <<
str.substr(prev, pos-prev) <<
"\\n\"\n";
2437 s <<
"\"" <<
str.substr(prev) <<
"\"";
2438 for (casadi_int i=0; i<
arg.size(); ++i) s <<
", " <<
arg[i];
2444 std::vector<std::string>
arg;
2445 arg.push_back(arg1);
2450 const std::string& arg2) {
2451 std::vector<std::string>
arg;
2452 arg.push_back(arg1);
2453 arg.push_back(arg2);
2458 const std::string& arg2,
const std::string& arg3) {
2459 std::vector<std::string>
arg;
2460 arg.push_back(arg1);
2461 arg.push_back(arg2);
2462 arg.push_back(arg3);
2467 const std::string& x,
const std::string& y) {
2469 return "casadi_axpy(" +
str(n) +
", " + a +
", " + x +
", " + y +
");";
2473 const std::string& min,
const std::string& mask) {
2475 return "casadi_clip_min(" + x +
", " +
str(n) +
", " +
min +
", " + mask +
");";
2479 const std::string& min,
const std::string& mask) {
2481 return "casadi_clip_max(" + x +
", " +
str(n) +
", " +
min +
", " + mask +
");";
2485 const std::string& y,
const std::string& z) {
2487 return "casadi_vector_fmax(" +
str(n) +
", " + x +
", " + y +
", " + z +
");";
2491 const std::string& y,
const std::string& z) {
2493 return "casadi_vector_fmin(" +
str(n) +
", " + x +
", " + y +
", " + z +
");";
2497 const std::string& mask) {
2499 return "casadi_masked_norm_inf(" +
str(n) +
", " + x +
", " + mask +
")";
2504 return "casadi_scal(" +
str(n) +
", " + alpha +
", " + x +
");";
2508 const std::string& y,
const std::string& z,
bool tr) {
2510 return "casadi_mv(" + x +
", " +
sparsity(sp_x) +
", " + y +
", "
2511 + z +
", " + (tr ?
"1" :
"0") +
");";
2515 const std::string& y,
const std::string& z,
bool tr) {
2517 return "casadi_mv_dense(" + x +
", " +
str(nrow_x) +
", " +
str(ncol_x) +
", "
2518 + y +
", " + z +
", " + (tr ?
"1" :
"0") +
");";
2522 const std::string& y,
const Sparsity& sp_y,
2523 const std::string& z,
const Sparsity& sp_z,
2524 const std::string& w,
bool tr) {
2526 return "casadi_mtimes(" + x +
", " +
sparsity(sp_x) +
", " + y +
", " +
sparsity(sp_y) +
", "
2527 + z +
", " +
sparsity(sp_z) +
", " + w +
", " + (tr ?
"1" :
"0") +
");";
2531 const std::string& y, casadi_int ncol_y,
2532 const std::string& z,
bool tr) {
2534 return "casadi_mtimes_dense(" + x +
", " +
str(nrow_x) +
", " +
str(ncol_x) +
", "
2535 + y +
", " +
str(ncol_y) +
", " + z +
", " + (tr ?
"1" :
"0") +
");";
2539 const std::string& y,
const Sparsity& sp_y,
const std::string& z) {
2541 return "casadi_mtimes_dense_sparse(" + x +
", " +
str(nrow_x) +
", "
2542 + y +
", " +
sparsity(sp_y) +
", " + z +
");";
2546 const std::string& y,
bool tr,
bool unity, casadi_int nrhs) {
2548 return "casadi_trilsolve(" +
sparsity(sp_x) +
", " + x +
", " + y +
", " +
str(tr) +
", "
2549 +
str(unity) +
", " +
str(nrhs) +
");";
2553 const std::string& y,
bool tr,
bool unity, casadi_int nrhs) {
2555 return "casadi_triusolve(" +
sparsity(sp_x) +
", " + x +
", " + y +
", " +
str(tr) +
", "
2556 +
str(unity) +
", " +
str(nrhs) +
");";
2562 std::stringstream s;
2563 s <<
"casadi_logsumexp(" << A <<
", " << n <<
");";
2569 if (s.empty())
return;
2573 casadi_int shift = s.front()==
'}' ? -1 : 0;
2587 }
else if (c==
'}') {
2597 size_t pos = s.find(
'\n', off);
2598 if (pos==std::string::npos) {
2616 this->
buffer.str(std::string());
2620 const std::string& ref) {
2628 casadi_assert(it->second.first==type,
"Type mismatch for " +
name);
2629 casadi_assert(it->second.second==ref,
"Type mismatch for " +
name);
2635 return "w[" +
str(i) +
"]";
2649 casadi_assert(it->second==def,
"Initial value mismatch for " +
name);
2658 size_t n1 = line.find(
'"', pos);
2659 casadi_assert(n1 != std::string::npos,
"Missing quoted token in: " + line);
2662 for (; i < line.size(); ++i) {
2663 if (line[i] ==
'\\' && i + 1 < line.size()) {
2665 }
else if (line[i] ==
'"') {
2671 casadi_assert(i < line.size(),
"Unterminated quoted token in: " + line);
2678 const std::vector<std::string>& inst,
bool add_shorthand) {
2681 for (
const std::string& s : inst) {
2682 if (s!=
"casadi_real") {
2683 for (
const std::string& s : inst)
suffix +=
"_" + s;
2689 std::vector<std::pair<std::string, std::string> > rep;
2690 for (casadi_int i=0; i<inst.size(); ++i) {
2691 rep.push_back(std::make_pair(
"T" +
str(i+1), inst[i]));
2695 std::stringstream ret;
2698 std::istringstream stream(src);
2700 bool filter_macros =
true;
2704 std::string active_symbol;
2706 while (std::getline(stream, line)) {
2710 if (line.find(
"template")==0)
continue;
2713 if (filter_macros && line.find(
"#define")==0)
continue;
2714 if (filter_macros && line.find(
"#undef")==0)
continue;
2717 if (line.find(
"casadi_assert") != std::string::npos)
continue;
2718 if (line.find(
"casadi_error") != std::string::npos)
continue;
2719 if (line.find(
"casadi_message") != std::string::npos)
continue;
2722 if (line ==
"inline")
continue;
2725 if (line.find(
"// SYMBOL") != std::string::npos) {
2726 n1 = line.find(
"\"");
2727 n2 = line.find(
"\"", n1+1);
2728 std::string sym = line.substr(n1+1, n2-n1-1);
2731 rep.push_back(std::make_pair(sym, sym +
suffix));
2733 active_symbol =
"casadi_" + sym;
2738 if (line.find(
"// C-REPLACE") != std::string::npos) {
2740 size_t pos = line.find(
"// C-REPLACE");
2744 rep.push_back(std::make_pair(key, sub));
2749 if (!
verbose_runtime && line.find(
"// C-VERBOSE") != std::string::npos) {
2751 std::getline(stream, line);
2755 if (line.find(
"// FILTER-MACROS ON") != std::string::npos) {
2756 filter_macros =
true;
2759 if (line.find(
"// FILTER-MACROS OFF") != std::string::npos) {
2760 filter_macros =
false;
2764 n1 = line.find(
"//");
2765 if (n1 != std::string::npos) line.erase(n1);
2768 n1 = line.find_last_not_of(
' ');
2769 if (n1 != std::string::npos) {
2776 if (!active_symbol.empty() &&
2777 line.find(active_symbol +
"(") != std::string::npos) {
2778 std::string sig_prefix;
2779 if (this->
static_aux) sig_prefix +=
"static ";
2780 if (this->
inline_aux) sig_prefix +=
"inline ";
2781 if (!sig_prefix.empty()) line = sig_prefix + line;
2782 active_symbol.clear();
2786 for (
auto&& it = rep.rbegin(); it!=rep.rend(); ++it) {
2787 line =
replace(line, it->first, it->second);
2791 ret << line <<
"\n";
2801 *
this <<
"/* " << s <<
" */\n";
2807 const std::vector<Sparsity>& sp_in,
2808 const std::vector<Sparsity>& sp_out) {
2813 *
this <<
declare(
"const casadi_int* " +
name +
"_sparsity_in(casadi_int i)") <<
" {\n"
2814 <<
"switch (i) {\n";
2815 for (casadi_int i=0; i<sp_in.size(); ++i) {
2818 *
this <<
"default: return 0;\n}\n"
2822 *
this <<
declare(
"const casadi_int* " +
name +
"_sparsity_out(casadi_int i)") <<
" {\n"
2823 <<
"switch (i) {\n";
2824 for (casadi_int i=0; i<sp_out.size(); ++i) {
2827 *
this <<
"default: return 0;\n}\n"
2832 qr(
const std::string& sp,
const std::string& A,
const std::string& w,
2833 const std::string& sp_v,
const std::string& v,
const std::string& sp_r,
2834 const std::string& r,
const std::string& beta,
const std::string& prinv,
2835 const std::string& pc) {
2837 return "casadi_qr(" + sp +
", " + A +
", " + w +
", "
2838 + sp_v +
", " + v +
", " + sp_r +
", " + r +
", "
2839 + beta +
", " + prinv +
", " + pc +
");";
2843 det(
const std::string& sp_v,
const std::string& v,
2844 const std::string& sp_r,
const std::string& r,
const std::string& beta) {
2846 return "casadi_det(" + sp_v +
", " + v +
", " + sp_r +
", " + r +
", " + beta +
")";
2850 qr_solve(
const std::string& x, casadi_int nrhs,
bool tr,
2851 const std::string& sp_v,
const std::string& v,
2852 const std::string& sp_r,
const std::string& r,
2853 const std::string& beta,
const std::string& prinv,
2854 const std::string& pc,
const std::string& w) {
2856 return "casadi_qr_solve(" + x +
", " +
str(nrhs) +
", " + (tr ?
"1" :
"0") +
", "
2857 + sp_v +
", " + v +
", " + sp_r +
", " + r +
", "
2858 + beta +
", " + prinv +
", " + pc +
", " + w +
");";
2862 lsqr_solve(
const std::string& A,
const std::string&x,
2863 casadi_int nrhs,
bool tr,
const std::string& sp,
const std::string& w) {
2865 return "casadi_lsqr_solve(" + A +
", " + x +
", " +
str(nrhs) +
", "
2866 + (tr ?
"1" :
"0") +
", " + sp +
", " + w +
");";
2870 ldl(
const std::string& sp_a,
const std::string& a,
2871 const std::string& sp_lt,
const std::string& lt,
const std::string& d,
2872 const std::string& p,
const std::string& w) {
2874 return "casadi_ldl(" + sp_a +
", " + a +
", " + sp_lt +
", " + lt +
", "
2875 + d +
", " + p +
", " + w +
");";
2879 ldl_solve(
const std::string& x, casadi_int nrhs,
2880 const std::string& sp_lt,
const std::string& lt,
const std::string& d,
2881 const std::string& p,
const std::string& w) {
2883 return "casadi_ldl_solve(" + x +
", " +
str(nrhs) +
", " + sp_lt +
", "
2884 + lt +
", " + d +
", " + p +
", " + w +
");";
2888 fmax(
const std::string& x,
const std::string& y) {
2890 return "casadi_fmax(" + x +
", " + y +
");";
2894 fmin(
const std::string& x,
const std::string& y) {
2896 return "casadi_fmin(" + x +
", " + y +
");";
2900 vfmax(
const std::string& x, casadi_int n,
const std::string& y) {
2902 return "casadi_vfmax(" + x +
", " +
str(n) +
", " + y +
");";
2906 vfmin(
const std::string& x, casadi_int n,
const std::string& y) {
2908 return "casadi_vfmin(" + x +
", " +
str(n) +
", " + y +
");";
2912 vfmax(
const std::string& x,
const std::string& n,
const std::string& y) {
2914 return "casadi_vfmax(" + x +
", " + n +
", " + y +
");";
2918 vfmin(
const std::string& x,
const std::string& n,
const std::string& y) {
2920 return "casadi_vfmin(" + x +
", " + n +
", " + y +
");";
2924 max(
const std::string& x,
const std::string& y) {
2926 return "casadi_max(" + x +
", " + y +
")";
2930 min(
const std::string& x,
const std::string& y) {
2932 return "casadi_min(" + x +
", " + y +
")";
2936 mmax(
const std::string& x, casadi_int n,
bool is_dense) {
2938 return "casadi_mmax(" + x +
", " +
str(n) +
", " +
str(casadi_int(is_dense)) +
")";
2942 mmin(
const std::string& x, casadi_int n,
bool is_dense) {
2944 return "casadi_mmin(" + x +
", " +
str(n) +
", " +
str(casadi_int(is_dense)) +
")";
2948 max_viol(casadi_int n,
const std::string& x,
const std::string& lb,
const std::string& ub) {
2950 return "casadi_max_viol(" +
str(n) +
", " + x+
", " + lb +
", " + ub +
")";
2954 sum_viol(casadi_int n,
const std::string& x,
const std::string& lb,
const std::string& ub) {
2956 return "casadi_sum_viol(" +
str(n) +
", " + x+
", " + lb +
", " + ub +
")";
2960 norm_inf(casadi_int n,
const std::string& x) {
2962 return "casadi_norm_inf(" +
str(n) +
", " + x +
")";
2966 norm_1(casadi_int n,
const std::string& x) {
2968 return "casadi_norm_1(" +
str(n) +
", " + x +
")";
2972 norm_2(casadi_int n,
const std::string& x) {
2974 return "casadi_norm_2(" +
str(n) +
", " + x +
")";
2980 return "casadi_lb_eig(" +
sparsity(sp_h) +
", " + h +
")";
2986 return "casadi_regularize(" +
sparsity(sp_h) +
", " + h +
", " + reg +
");";
2991 const std::string& Hin,
const std::string& Hout,
const std::string& iw,
const std::string& w) {
2997 low(
const std::string& x,
const std::string& grid, casadi_int ng, casadi_int lookup_mode) {
2999 return "casadi_low(" + x +
", " + grid +
", " +
str(ng) +
", " +
str(lookup_mode) +
");";
3004 const std::string& lam,
const std::string& lbx,
const std::string& ubx) {
3006 return "casadi_bound_consistency(" +
str(n) +
", " + x +
", " + lam +
3007 ", " + lbx +
", " + ubx +
")";
3011 file_slurp(
const std::string& fname, casadi_int n,
const std::string& a) {
3013 return "casadi_file_slurp(\"" + fname +
"\", " +
str(n) +
", " + a +
")";
3017 to_file(
const std::string& f,
const Sparsity& sp,
const std::string& x) {
3019 return "casadi_to_file(" + f +
", " +
sparsity(sp) +
", " + x +
")";
3024 casadi_int n = is_input ? f.
n_in() : f.
n_out();
3028 if (!effective_dir.empty())
prefix = effective_dir +
"/";
3029 std::string inout = is_input ?
"in" :
"out";
3035 "Unable to create the required directory for '" + dir +
"'.");
3040 for (casadi_int i = 0; i < n; ++i) {
3043 std::string fixed_part =
prefix + f.
name() +
"." + inout +
"." + io_name +
"." + dump_format;
3044 casadi_int buf_size = fixed_part.size() + 1 + 6 + 1;
3046 *
this <<
"char dump_fname[" << buf_size <<
"];\n";
3047 *
this <<
"FILE* dump_file;\n";
3048 *
this <<
"snprintf(dump_fname, " << buf_size <<
", \""
3049 <<
prefix << f.
name() <<
".%06d." << inout <<
"." << io_name
3050 <<
"." << dump_format <<
"\", dump_id_local);\n";
3052 *
this <<
printf(
"dump -> %s\\n",
"dump_fname") <<
"\n";
3054 *
this <<
"dump_file = fopen(dump_fname, \"w\");\n";
3055 *
this <<
"if (dump_file) {\n";
3056 *
this <<
to_file(
"dump_file", sp, arr +
"[" +
str(i) +
"]") <<
";\n";
3057 *
this <<
"fclose(dump_file);\n";
3064 std::string fixed_part =
prefix + f.
name() +
"." + inout +
".txt";
3065 casadi_int buf_size = fixed_part.size() + 1 + 6 + 1;
3067 *
this <<
"char dump_fname[" << buf_size <<
"];\n";
3068 *
this <<
"FILE* dump_file;\n";
3069 *
this <<
"casadi_int dump_k;\n";
3070 *
this <<
"snprintf(dump_fname, " << buf_size <<
", \""
3071 <<
prefix << f.
name() <<
".%06d." << inout <<
".txt\", dump_id_local);\n";
3072 *
this <<
"dump_file = fopen(dump_fname, \"w\");\n";
3073 *
this <<
"if (dump_file) {\n";
3074 for (casadi_int i = 0; i < n; ++i) {
3076 casadi_int nnz = sp.
nnz();
3077 std::string a = arr +
"[" +
str(i) +
"]";
3079 *
this <<
"if (" << a <<
") {\n";
3081 *
this <<
"fprintf(dump_file, \"\\n\");\n";
3082 *
this <<
"} else {\n";
3083 std::string zero_str = is_input ?
"0.0000000000000000e+00" :
"nan";
3084 *
this <<
"for (dump_k=0; dump_k<" << nnz <<
"; ++dump_k) "
3085 <<
"fprintf(dump_file, \"" << zero_str <<
"\\n\");\n";
3089 *
this <<
"fclose(dump_file);\n";
3097 casadi_int n = is_input ? f.
n_in() : f.
n_out();
3098 std::string inout = is_input ?
"Input" :
"Output";
3100 *
this <<
printf(
"Function " + f.
name() +
"\\n") <<
"\n";
3101 for (casadi_int i = 0; i < n; ++i) {
3104 *
this <<
printf(inout +
" " +
str(i) +
" (" + io_name +
"): ") <<
"\n";
3106 *
this <<
printf(
"\\n") <<
"\n";
3111 cache_check(
const std::string& key,
const std::string& cache,
const std::string& loc,
3112 casadi_int stride, casadi_int sz, casadi_int key_sz,
const std::string& val) {
3114 return "casadi_cache_check(" + key +
", " + cache +
", " + loc +
", " +
3115 str(stride) +
", " +
str(sz) +
", " +
str(key_sz) +
", " + val +
")";
3119 sz_arg = sz_res = sz_iw = sz_w = 0;
3121 sz_arg = std::max(sz_arg, f.f.sz_arg());
3122 sz_res = std::max(sz_res, f.f.sz_res());
3123 sz_iw = std::max(sz_iw, f.f.sz_iw());
3124 sz_w = std::max(sz_w, f.f.sz_w());
static bool codegen_dot_aux(CodeGenerator &g, const std::vector< std::string > &inst)
static bool codegen_norm_1_aux(CodeGenerator &g, const std::vector< std::string > &inst)
static void codegen_copy_aux(CodeGenerator &g, const std::vector< std::string > &inst)
static bool codegen_scal_aux(CodeGenerator &g, const std::vector< std::string > &inst)
static bool codegen_axpy_aux(CodeGenerator &g, const std::vector< std::string > &inst)
static bool codegen_norm_2_aux(CodeGenerator &g, const std::vector< std::string > &inst)
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
void scope_add_cleanup(const std::string &code)
Add cleanup code to be executed upon scope exit.
std::set< std::string > external_names_
const std::set< std::string > & local_mutexes(const Function &f) const
Get all mutex names associated with a function.
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.
bool thread_safe() const
Emit thead safe code chekout/release?
std::vector< std::string > local_cleanup_
std::map< std::string, std::string > local_default_
std::map< const FunctionInternal *, std::set< std::string > > local_mutexes_
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.
void generate_dump(const Function &f, const std::string &arr, bool is_input)
Generate dump_in or dump_out code for a function call.
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 to_file(const std::string &f, const Sparsity &sp, const std::string &x)
Write matrix to file in MatrixMarket format.
std::string casadi_int_type
std::string dump_dir_suffix
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 fprintf_scalar(const std::string &f, const std::string &arg)
fprintf a normalized scalar (canonical nan/inf) to a file
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 dump_dir_prefix
void generate_print(const Function &f, const std::string &arr, bool is_input)
Generate print_in or print_out code for a function call.
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.
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::string fprintf_vector(const std::string &f, casadi_int sz, const std::string &arg, const std::string &sep)
fprintf a normalized vector to a file with a separator
std::vector< std::vector< double > > double_constants_
std::map< const FunctionInternal *, size_t > codegen_sz_w_
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.
void add_external(const std::string &new_external, const std::string &name="")
Add an external function declaration.
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.
std::string mtimes_dense_sparse(const std::string &x, casadi_int nrow_x, const std::string &y, const Sparsity &sp_y, const std::string &z)
Codegen dense-sparse matrix-matrix multiplication (z, x dense)
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 local_mutex(const Function &f, const std::string &name) const
Access a static mutex associated with a function.
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.
std::string det(const std::string &sp_v, const std::string &v, const std::string &sp_r, const std::string &r, const std::string &beta)
Determinant from sparse QR factors.
casadi_int max_declarations_per_line
bool get_codegen_sz_w(const FunctionInternal *f, size_t &sz_w) const
Retrieve a work vector size registered by set_codegen_sz_w.
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_5D_BOOR_EVAL
@ AUX_KRON_CONTRACT_INNER_DENSE
@ AUX_KRON_CONTRACT_INNER
@ AUX_BLAZING_2D_BOOR_EVAL
@ AUX_BLAZING_4D_BOOR_EVAL
@ AUX_KRON_CONTRACT_OUTER_SPARSE_DENSE
@ AUX_KRON_CONTRACT_OUTER_DENSE_SPARSE
@ AUX_BLAZING_1D_BOOR_EVAL
@ AUX_KRON_CONTRACT_OUTER_DENSE
@ AUX_INTERPN_INTERPOLATE
@ AUX_KRON_CONTRACT_OUTER
@ AUX_KRON_CONTRACT_INNER_SPARSE_DENSE
@ AUX_BLAZING_3D_BOOR_EVAL
@ AUX_KRON_CONTRACT_INNER_DENSE_SPARSE
@ AUX_MTIMES_DENSE_SPARSE
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.
void scope_return()
Return from a scope without a value.
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
void set_codegen_sz_w(const FunctionInternal *f, size_t sz_w)
Register the work vector size a function needs in generated code.
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.
void define_local_mutex(const Function &f, const std::string &name)
Declare a static mutex associated with a 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::string ensure_trailing_slash(const std::string &path)
static bool ensure_directory_exists(const std::string &path)
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.
std::vector< Sparsity > sparsity_in_
Input and output sparsity.
virtual void codegen_decref(CodeGenerator &g) const
Codegen decref for dependencies.
virtual bool codegen_mem_is_opaque() const
Is thread-local memory object managed by checkout/release.
virtual void codegen_free_mem(CodeGenerator &g) const
Codegen for free_mem.
std::string signature_unrolled(const std::string &fname) const
Code generate the function.
bool has_refcount_in_deps_
Reference counting in dependent functions.
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 bool codegen_needs_mem() const
Is thread-local memory object needed?
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_incref(CodeGenerator &g) const
Codegen incref for dependencies.
const Sparsity & sparsity_out(casadi_int ind) const
Get sparsity of a given output.
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.
const Sparsity & sparsity_in(casadi_int ind) const
Get sparsity of a given input.
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
bool verbose_
Verbose printout.
casadi_int nnz() const
Get the number of (structural) non-zeros.
std::vector< casadi_int > compress(bool canonical=true) const
Compress a sparsity pattern.
static const std::set< std::string > empty_mutex_set_
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 next_quoted_token(const std::string &line, size_t &pos)
static std::string print(unsigned char op, const std::string &x, const std::string &y)
Print.