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 <<
" for (jj=0; jj<sp[0]*sp[1]; ++jj) y[ii][jj] = 0;\n"
799 <<
" jj_total = 0;\n"
800 <<
" ind_start_row_index = 2 + sp[1] + 1;\n\n"
801 <<
" /* Distribute nonzero elements column by column */\n"
802 <<
" for (col=0; col<sp[1]; col++) {\n\n"
803 <<
" /* The cumulative sum of nonzero elements after each column starts at index 2, "
804 "after last entry of CCS array col_ptr; number of nonzero elements in current column is "
805 "obtained by the difference of two consecutive values */\n"
806 <<
" nnz_col = sp[2+col+1] - sp[2+col];\n\n"
807 <<
" /* Distribute nonzero elements of current column to correct row position */\n"
808 <<
" for (jj=0; jj<nnz_col; jj++) {\n"
809 <<
" row = sp[ind_start_row_index+jj_total];\n"
810 <<
" y[ii][row + sp[0]*col] = res[ii][jj_total];\n"
816 <<
" for (jj=0; jj<sp[0]*sp[1]; ++jj) y[ii][jj] = res[ii][jj];\n"
822 g <<
"/* Function: mdlTerminate =================================================\n"
824 <<
" * In this function, you should perform any actions that are necessary\n"
825 <<
" * at the termination of a simulation.\n"
827 <<
"static void mdlTerminate(SimStruct *S)\n"
830 <<
"/* Required S-function trailer */\n"
831 <<
"#ifdef MATLAB_MEX_FILE\n"
832 <<
"# include \"simulink.c\"\n"
834 <<
"# include \"cg_sfun.h\"\n"
840 void CodeGenerator::generate_main(std::ostream &s)
const {
841 s << this->
dll_export <<
"int main(int argc, char* argv[]) {\n";
844 s <<
" if (argc<2) {\n"
845 <<
" /* name error */\n";
847 s <<
" } else if (strcmp(argv[1], \"" <<
exposed_fname[i] <<
"\")==0) {\n"
848 <<
" return main_" <<
exposed_fname[i] <<
"(argc-2, argv+2);\n";
853 s <<
" fprintf(stderr, \"First input should be a command string. Possible values:";
858 s <<
"Note: you may use function.generate_input to create a command string.";
877 return "casadi_rd" +
str(size);
891 return "casadi_ri" +
str(size);
909 return "casadi_pd" +
str(it->second);
913 const std::string& name) {
917 auxiliaries <<
"#if CASADI_MUTEX_USE_STATIC_INIT == 0\n";
918 auxiliaries <<
"static CASADI_MUTEX_TYPE " << sh <<
";\n";
921 <<
" = CASADI_MUTEX_STATIC_INIT;\n";
926 const std::string& name)
const {
929 "Mutex not defined: " +
name);
947 s <<
"/* How to prefix internal symbols */\n"
948 <<
"#ifdef CASADI_CODEGEN_PREFIX\n"
949 <<
" #define CASADI_NAMESPACE_CONCAT(NS, ID) _CASADI_NAMESPACE_CONCAT(NS, ID)\n"
950 <<
" #define _CASADI_NAMESPACE_CONCAT(NS, ID) NS ## ID\n"
951 <<
" #define CASADI_PREFIX(ID) CASADI_NAMESPACE_CONCAT(CODEGEN_PREFIX, ID)\n"
953 <<
" #define CASADI_PREFIX(ID) " << this->
prefix <<
"_ ## ID\n"
961 generate_casadi_real(s);
964 generate_casadi_int(s);
967 s <<
"#ifndef CASADI_MAX_NUM_THREADS\n";
968 s <<
"#define CASADI_MAX_NUM_THREADS 1\n";
975 s <<
"#include <casadi/mem.h>\n" << std::endl;
980 s <<
"/* Add prefix to internal symbols */\n";
982 s <<
"#define " <<
"casadi_" << i <<
" CASADI_PREFIX(" << i <<
")\n";
1001 s <<
"/* Configuration this file was compiled with */\n"
1002 <<
declare(
"void " + this->prefix +
"_casadi_version(int* major, int* minor, int* patch)")
1004 <<
" *major = " << CASADI_MAJOR_VERSION <<
";\n"
1005 <<
" *minor = " << CASADI_MINOR_VERSION <<
";\n"
1006 <<
" *patch = " << CASADI_PATCH_VERSION <<
";\n"
1008 <<
declare(
"int " + this->prefix +
"_casadi_int_size(void)")
1009 <<
" { return (int) sizeof(casadi_int); }\n"
1010 <<
declare(
"int " + this->prefix +
"_casadi_real_size(void)")
1011 <<
" { return (int) sizeof(casadi_real); }\n";
1013 s <<
declare(
"int " + this->prefix +
"_max_num_threads(void)")
1014 <<
" { return CASADI_MAX_NUM_THREADS; }\n";
1017 s <<
declare(
"int " + this->prefix +
"_thread_type(void)")
1018 <<
" { return CASADI_THREAD_TYPE; }\n";
1055 std::vector<double> sz_zeros(
sz_zeros_, 0);
1056 print_vector(s,
"casadi_zeros", std::vector<double>(sz_zeros));
1061 std::vector<double> sz_ones(
sz_ones_, 0);
1062 print_vector(s,
"casadi_ones", std::vector<double>(sz_ones));
1070 s <<
"static casadi_real casadi_rd" +
str(i++) +
"[" +
str(it.second) +
"];\n";
1079 s <<
"static casadi_real casadi_ri" +
str(i++) +
"[" +
str(it.second) +
"];\n";
1088 s <<
"casadi_real casadi_pd" +
str(i) +
1097 s <<
"/* External functions */\n";
1099 s << i << std::endl;
1101 s << std::endl << std::endl;
1105 s << this->
body.str();
1125 if (n<0)
return "0";
1126 std::stringstream s;
1153 std::stringstream ss;
1160 const std::string& def) {
1161 std::stringstream s;
1164 s <<
"*" <<
name <<
" = 0";
1166 s <<
name <<
"[" << len <<
"]";
1167 if (!def.empty()) s <<
" = " << def;
1174 const std::vector<casadi_int>& v) {
1179 const std::vector<char>& v) {
1184 const std::vector<double>& v) {
1189 const std::vector<std::string>& v) {
1195 std::stringstream s;
1196 s <<
"casadi_print_canonical(" <<
sparsity(sp) <<
", " <<
arg <<
");";
1202 std::stringstream s;
1203 s <<
"casadi_print_vector(" << sz <<
", " <<
arg <<
");";
1209 std::stringstream s;
1210 s <<
"casadi_print_scalar(" <<
arg <<
");";
1216 std::stringstream s;
1217 s <<
"casadi_fprintf_scalar(" << f <<
", " <<
arg <<
");";
1222 const std::string& arg,
const std::string& sep) {
1224 std::stringstream s;
1225 s <<
"casadi_fprintf_vector(" << f <<
", " << sz <<
", " <<
arg <<
", \"" << sep <<
"\");";
1233 return "casadi_fabs("+a0+
")";
1236 return "casadi_sq("+a0+
")";
1239 return "casadi_sign("+a0+
")";
1242 return "casadi_log1p("+a0+
")";
1245 return "casadi_expm1("+a0+
")";
1254 return "casadi_fmin("+a0+
","+a1+
")";
1257 return "casadi_fmax("+a0+
","+a1+
")";
1260 return "casadi_hypot("+a0+
","+a1+
")";
1263 return "casadi_printme("+a0+
","+a1+
")";
1270 const std::string& use_ifdef) {
1278 if (!use_ifdef.empty()) this->
includes <<
"#ifdef " << use_ifdef << std::endl;
1281 if (relative_path) {
1282 this->
includes <<
"#include \"" << new_include <<
"\"\n";
1284 this->
includes <<
"#include <" << new_include <<
">\n";
1288 if (!use_ifdef.empty()) this->
includes <<
"#endif\n";
1295 *
this << s <<
".checkout = " <<
name <<
"_checkout;\n";
1297 *
this << s <<
".checkout = 0;\n";
1300 *
this << s <<
".eval = " <<
name <<
";\n";
1302 *
this << s <<
".release = " <<
name <<
"_release;\n";
1304 *
this << s <<
".release = 0;\n";
1310 const std::string& res,
const std::string& iw,
1311 const std::string& w,
const std::string& failure_ret) {
1317 std::string
mem =
"mid";
1318 local(
"flag",
"int");
1320 std::string checkout =
shorthand(cg_name +
"_checkout");
1321 *
this <<
mem <<
" = " << checkout <<
"();\n";
1322 if (failure_ret.empty()) {
1323 *
this <<
"if (" <<
mem <<
"<0) {\n";
1324 *
this <<
"flag = 1;\n";
1325 *
this <<
"} else {\n";
1327 *
this <<
"if (" <<
mem <<
"<0) return " << failure_ret <<
";\n";
1330 *
this <<
"flag = " +
name +
"(" +
arg +
", " +
res +
", "
1331 + iw +
", " + w +
", " <<
mem <<
");\n";
1333 if (failure_ret.empty()) {
1337 std::string release =
shorthand(cg_name +
"_release");
1338 *
this << release <<
"(" <<
mem <<
");\n";
1342 + iw +
", " + w +
", 0)";
1347 if (!
name.empty()) {
1350 "Cannot code generate '" +
name +
"': name conflicts with an external dependency.");
1358 return "casadi_" +
name;
1363 if (!allow_adding) {
1364 casadi_assert(added,
"Duplicate macro: " +
name);
1366 return "casadi_" +
name;
1385 casadi_assert_dev(
sizeof(
double) %
sizeof(
size_t)==0);
1386 const casadi_int int_len = v.size()*(
sizeof(double)/
sizeof(
size_t));
1387 const size_t* int_v =
reinterpret_cast<const size_t*
>(&v.front());
1388 for (
size_t i=0; i<int_len; ++i) {
1419 for (
auto 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");
1486 std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> eq =
1488 for (std::multimap<size_t, size_t>::iterator i=eq.first; i!=eq.second; ++i) {
1499 casadi_error(
"Constant not found");
1527 const std::string& name,
const std::vector<casadi_int>& v,
const std::string& type) {
1536 (*this) <<
"for (i=0;i<" << v.size() <<
";++i) " +
name +
"[i] = " + ref +
"[i];\n";
1550 for (
auto it=f_match.first; it!=f_match.second; ++it) {
1551 if (it->second==inst)
return;
1742 std::vector<std::string> inst2 = inst;
1743 if (inst.size()==1) inst2.push_back(inst[0]);
1750 std::vector<std::string> inst2 = inst;
1751 if (inst.size()==1) inst2.push_back(inst[0]);
1966 this->
auxiliaries <<
"#define casadi_to_double(x) "
1967 <<
"(" << (this->
cpp ?
"static_cast<double>(x)" :
"(double) x") <<
")\n\n";
1971 <<
"(" << (this->
cpp ?
"static_cast<casadi_int>(x)" :
"(casadi_int) x")
1976 <<
"(" << (this->
cpp ?
"static_cast<x>(y)" :
"(x) y") <<
")\n\n";
1980 "// SYMBOL \"sq\"\n"
1981 "casadi_real casadi_sq(casadi_real x) { return x*x;}\n\n",
1986 "// SYMBOL \"sign\"\n"
1987 "casadi_real casadi_sign(casadi_real x) "
1988 "{ return x<0 ? -1 : x>0 ? 1 : x;}\n\n",
1993 "// SYMBOL \"if_else\"\n"
1994 "casadi_real casadi_if_else"
1995 "(casadi_real c, casadi_real x, casadi_real y) "
1996 "{ return c!=0 ? x : y;}\n\n",
2003 <<
" #define CASADI_PRINTF mexPrintf\n"
2005 <<
" #define CASADI_PRINTF printf\n"
2009 this->
auxiliaries <<
"#define CASADI_PRINTF printf\n";
2011 this->
auxiliaries <<
"#define CASADI_SNPRINTF snprintf\n";
2018 "// SYMBOL \"fmin\"\n"
2019 "casadi_real casadi_fmin(casadi_real x, casadi_real y) {\n"
2020 "/* Pre-c99 compatibility */\n"
2021 "#if __STDC_VERSION__ < 199901L\n"
2022 " return x<y ? x : y;\n"
2024 " return fmin(x, y);\n"
2031 "// SYMBOL \"fmax\"\n"
2032 "casadi_real casadi_fmax(casadi_real x, casadi_real y) {\n"
2033 "/* Pre-c99 compatibility */\n"
2034 "#if __STDC_VERSION__ < 199901L\n"
2035 " return x>y ? x : y;\n"
2037 " return fmax(x, y);\n"
2044 "// SYMBOL \"fabs\"\n"
2045 "casadi_real casadi_fabs(casadi_real x) {\n"
2046 "/* Pre-c99 compatibility */\n"
2047 "#if __STDC_VERSION__ < 199901L\n"
2048 " return x>0 ? x : -x;\n"
2050 " return fabs(x);\n"
2057 "// SYMBOL \"isinf\"\n"
2058 "casadi_real casadi_isinf(casadi_real x) {\n"
2059 "/* Pre-c99 compatibility */\n"
2060 "#if __STDC_VERSION__ < 199901L\n"
2061 " return x== INFINITY || x==-INFINITY;\n"
2063 " return isinf(x);\n"
2070 "// SYMBOL \"isfinite\"\n"
2071 "casadi_real casadi_isfinite(casadi_real x) {\n"
2072 "/* Pre-c99 compatibility */\n"
2073 "#if __STDC_VERSION__ < 199901L\n"
2074 " return x==x && x!=INFINITY && x!=-INFINITY;\n"
2076 " return isfinite(x);\n"
2083 "// SYMBOL \"min\"\n"
2084 "casadi_int casadi_min(casadi_int x, casadi_int y) {\n"
2085 " return x>y ? y : x;\n"
2091 "// SYMBOL \"max\"\n"
2092 "casadi_int casadi_max(casadi_int x, casadi_int y) {\n"
2093 " return x>y ? x : y;\n"
2109 <<
" #define casadi_inf " << this->
infinity <<
"\n"
2114 <<
" #define casadi_nan " << this->
nan <<
"\n"
2119 <<
" #define casadi_real_min " << this->
real_min <<
"\n"
2124 "// SYMBOL \"log1p\"\n"
2125 "casadi_real casadi_log1p(casadi_real x) {\n"
2126 "/* Pre-c99 compatibility */\n"
2127 "#if __STDC_VERSION__ < 199901L\n"
2128 " return log(1+x);\n"
2130 " return log1p(x);\n"
2137 "// SYMBOL \"expm1\"\n"
2138 "casadi_real casadi_expm1(casadi_real x) {\n"
2139 "/* Pre-c99 compatibility */\n"
2140 "#if __STDC_VERSION__ < 199901L\n"
2141 " return exp(x)-1;\n"
2143 " return expm1(x);\n"
2150 "// SYMBOL \"hypot\"\n"
2151 "casadi_real casadi_hypot(casadi_real x, casadi_real y) {\n"
2152 "/* Pre-c99 compatibility */\n"
2153 "#if __STDC_VERSION__ < 199901L\n"
2154 " return sqrt(x*x+y*y);\n"
2156 " return hypot(x, y);\n"
2225 std::stringstream s;
2226 s <<
"casadi_to_mex(" <<
sparsity(sp) <<
", " <<
arg <<
");";
2231 const std::string& res, std::size_t res_off,
2232 const Sparsity& sp_res,
const std::string& w) {
2237 std::stringstream s;
2238 s <<
"casadi_from_mex(" <<
arg
2239 <<
", " <<
res <<
", " <<
sparsity(sp_res) <<
", " << w <<
");";
2245 std::stringstream ret;
2247 std::istringstream stream(casadi_fmu_str);
2248 while (std::getline(stream, line)) {
2250 if (line.find(
"MODELNAME") != std::string::npos) {
2251 line =
replace(line,
"MODELNAME", modelname);
2254 ret << line <<
"\n";
2260 std::string ret = v;
2261 ret =
replace(ret,
"\\",
"\\\\");
2262 ret =
replace(ret,
"\"",
"\\\"");
2263 return "\"" + ret +
"\"";
2271 return constant(
static_cast<casadi_int
>(v));
2274 std::stringstream s;
2278 }
else if (isinf(v)) {
2283 casadi_int v_int =
static_cast<casadi_int
>(v);
2284 if (
static_cast<double>(v_int)==v) {
2289 std::ios_base::fmtflags fmtfl = s.flags();
2290 s << std::scientific << std::setprecision(std::numeric_limits<double>::digits10 + 1) << v;
2298 std::size_t n,
const std::string& res) {
2299 std::stringstream s;
2302 s <<
"casadi_copy(" <<
arg <<
", " << n <<
", " <<
res <<
");";
2312 bool check_lhs,
bool check_rhs) {
2313 std::vector<std::string> checks;
2314 if (check_lhs) checks.push_back(
arg);
2315 if (check_rhs) checks.push_back(
res);
2316 if (!checks.empty()) *
this <<
"if (" <<
join(checks,
" && ") <<
") ";
2321 const std::string& def,
bool check_rhs) {
2322 *
this <<
"if (" <<
arg <<
") {\n";
2323 if (check_rhs) *
this <<
"if (" <<
res <<
") ";
2325 *
this <<
"} else {\n";
2326 if (check_rhs) *
this <<
"if (" <<
res <<
") ";
2327 *
this <<
fill(
res, n, def) <<
"\n";
2332 std::stringstream s;
2335 s <<
"casadi_clear(" <<
res <<
", " << n <<
");";
2340 return "arg[" +
str(i) +
"]";
2344 return "res[" +
str(i) +
"]";
2350 return mem_array+
"[mem]";
2354 std::size_t n,
const std::string& v) {
2356 std::stringstream s;
2359 s <<
"casadi_fill(" <<
res <<
", " << n <<
", " << v <<
");";
2364 const std::string& y) {
2366 std::stringstream s;
2367 s <<
"casadi_dot(" << n <<
", " << x <<
", " << y <<
")";
2372 const std::string& x,
const std::string& y) {
2374 std::stringstream s;
2375 s <<
"casadi_bilin(" << A <<
", " <<
sparsity(sp_A) <<
", " << x <<
", " << y <<
")";
2380 const std::string& alpha,
const std::string& x,
2381 const std::string& y) {
2383 std::stringstream s;
2384 s <<
"casadi_rank1(" << A <<
", " <<
sparsity(sp_A) <<
", "
2385 << alpha <<
", " << x <<
", " << y <<
");";
2390 const std::string& res, casadi_int ndim,
const std::string& grid,
2391 const std::string& offset,
2392 const std::string& values,
const std::string& x,
2393 const std::string& lookup_mode, casadi_int m,
2394 const std::string& iw,
const std::string& w) {
2396 std::stringstream s;
2397 s <<
"casadi_interpn(" <<
res <<
", " << ndim <<
", " << grid <<
", " << offset <<
", "
2398 << values <<
", " << x <<
", " << lookup_mode <<
", " << m <<
", " << iw <<
", " << w <<
");";
2403 casadi_int ndim,
const std::string& grid,
const std::string& offset,
2404 const std::string& values,
const std::string& x,
2405 const std::string& lookup_mode, casadi_int m,
2406 const std::string& iw,
const std::string& w) {
2408 std::stringstream s;
2409 s <<
"casadi_interpn_grad(" << grad <<
", " << ndim <<
", " << grid <<
", " << offset <<
", "
2410 << values <<
", " << x <<
", " << lookup_mode <<
"," << m <<
", " << iw <<
", " << w <<
");";
2415 const std::string& y,
const Sparsity& sp_y,
2416 const std::string& iw) {
2418 return "casadi_trans(" + x +
"," +
sparsity(sp_x) +
", "
2419 + y +
", " +
sparsity(sp_y) +
", " + iw +
")";
2424 std::string cpp_prefix = this->
cpp ?
"extern \"C\" " :
"";
2432 return cpp_prefix + this->dll_export + s;
2437 const std::string& res,
const Sparsity& sp_res,
2438 const std::string& w) {
2444 std::stringstream s;
2445 s <<
"casadi_project(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", " <<
res <<
", "
2446 <<
sparsity(sp_res) <<
", " << w <<
");";
2452 const std::string& res,
bool lower) {
2455 std::stringstream s;
2456 s <<
"casadi_tri_project(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", ";
2457 s <<
res <<
", " << (lower ? 1: 0) <<
");";
2463 const std::string& res,
bool tr) {
2466 std::stringstream s;
2467 s <<
"casadi_densify(" <<
arg <<
", " <<
sparsity(sp_arg) <<
", " <<
res <<
", "
2468 << (tr ? 1 : 0) <<
");";
2477 std::stringstream s;
2478 s <<
"casadi_sparsify(" <<
arg <<
", " <<
res <<
", "
2479 <<
sparsity(sp_res) <<
", " << (tr ? 1 : 0) <<
");";
2485 std::stringstream s;
2486 s <<
"CASADI_PRINTF(";
2488 std::string::size_type pos = 0, prev = 0;
2489 while ((pos =
str.find(
'\n', prev)) != std::string::npos) {
2491 s <<
"\"" <<
str.substr(prev, pos-prev) <<
"\\n\"\n";
2495 s <<
"\"" <<
str.substr(prev) <<
"\"";
2496 for (casadi_int i=0; i<
arg.size(); ++i) s <<
", " <<
arg[i];
2502 std::vector<std::string>
arg;
2503 arg.push_back(arg1);
2508 const std::string& arg2) {
2509 std::vector<std::string>
arg;
2510 arg.push_back(arg1);
2511 arg.push_back(arg2);
2516 const std::string& arg2,
const std::string& arg3) {
2517 std::vector<std::string>
arg;
2518 arg.push_back(arg1);
2519 arg.push_back(arg2);
2520 arg.push_back(arg3);
2525 const std::string& x,
const std::string& y) {
2527 return "casadi_axpy(" +
str(n) +
", " + a +
", " + x +
", " + y +
");";
2531 const std::string& min,
const std::string& mask) {
2533 return "casadi_clip_min(" + x +
", " +
str(n) +
", " +
min +
", " + mask +
");";
2537 const std::string& min,
const std::string& mask) {
2539 return "casadi_clip_max(" + x +
", " +
str(n) +
", " +
min +
", " + mask +
");";
2543 const std::string& y,
const std::string& z) {
2545 return "casadi_vector_fmax(" +
str(n) +
", " + x +
", " + y +
", " + z +
");";
2549 const std::string& y,
const std::string& z) {
2551 return "casadi_vector_fmin(" +
str(n) +
", " + x +
", " + y +
", " + z +
");";
2555 const std::string& mask) {
2557 return "casadi_masked_norm_inf(" +
str(n) +
", " + x +
", " + mask +
")";
2562 return "casadi_scal(" +
str(n) +
", " + alpha +
", " + x +
");";
2566 const std::string& y,
const std::string& z,
bool tr) {
2568 return "casadi_mv(" + x +
", " +
sparsity(sp_x) +
", " + y +
", "
2569 + z +
", " + (tr ?
"1" :
"0") +
");";
2573 const std::string& y,
const std::string& z,
bool tr) {
2575 return "casadi_mv_dense(" + x +
", " +
str(nrow_x) +
", " +
str(ncol_x) +
", "
2576 + y +
", " + z +
", " + (tr ?
"1" :
"0") +
");";
2580 const std::string& y,
const Sparsity& sp_y,
2581 const std::string& z,
const Sparsity& sp_z,
2582 const std::string& w,
bool tr) {
2584 return "casadi_mtimes(" + x +
", " +
sparsity(sp_x) +
", " + y +
", " +
sparsity(sp_y) +
", "
2585 + z +
", " +
sparsity(sp_z) +
", " + w +
", " + (tr ?
"1" :
"0") +
");";
2589 const std::string& y, casadi_int ncol_y,
2590 const std::string& z,
bool tr) {
2592 return "casadi_mtimes_dense(" + x +
", " +
str(nrow_x) +
", " +
str(ncol_x) +
", "
2593 + y +
", " +
str(ncol_y) +
", " + z +
", " + (tr ?
"1" :
"0") +
");";
2597 const std::string& y,
const Sparsity& sp_y,
const std::string& z) {
2599 return "casadi_mtimes_dense_sparse(" + x +
", " +
str(nrow_x) +
", "
2600 + y +
", " +
sparsity(sp_y) +
", " + z +
");";
2604 const std::string& y,
bool tr,
bool unity, casadi_int nrhs) {
2606 return "casadi_trilsolve(" +
sparsity(sp_x) +
", " + x +
", " + y +
", " +
str(tr) +
", "
2607 +
str(unity) +
", " +
str(nrhs) +
");";
2611 const std::string& y,
bool tr,
bool unity, casadi_int nrhs) {
2613 return "casadi_triusolve(" +
sparsity(sp_x) +
", " + x +
", " + y +
", " +
str(tr) +
", "
2614 +
str(unity) +
", " +
str(nrhs) +
");";
2620 std::stringstream s;
2621 s <<
"casadi_logsumexp(" << A <<
", " << n <<
");";
2627 if (s.empty())
return;
2631 casadi_int shift = s.front()==
'}' ? -1 : 0;
2645 }
else if (c==
'}') {
2655 size_t pos = s.find(
'\n', off);
2656 if (pos==std::string::npos) {
2674 this->
buffer.str(std::string());
2678 const std::string& ref) {
2686 casadi_assert(it->second.first==type,
"Type mismatch for " +
name);
2687 casadi_assert(it->second.second==ref,
"Type mismatch for " +
name);
2693 return "w[" +
str(i) +
"]";
2707 casadi_assert(it->second==def,
"Initial value mismatch for " +
name);
2716 size_t n1 = line.find(
'"', pos);
2717 casadi_assert(n1 != std::string::npos,
"Missing quoted token in: " + line);
2720 for (; i < line.size(); ++i) {
2721 if (line[i] ==
'\\' && i + 1 < line.size()) {
2723 }
else if (line[i] ==
'"') {
2729 casadi_assert(i < line.size(),
"Unterminated quoted token in: " + line);
2735 const std::vector<std::string>& inst) {
2736 std::string k = key;
2737 for (
const std::string& s : inst) k +=
"_" + s;
2743 const std::vector<std::string>& inst,
bool add_shorthand) {
2746 for (
const std::string& s : inst) {
2747 if (s!=
"casadi_real") {
2748 for (
const std::string& s : inst)
suffix +=
"_" + s;
2754 std::vector<std::pair<std::string, std::string> > rep;
2755 for (casadi_int i=0; i<inst.size(); ++i) {
2756 rep.push_back(std::make_pair(
"T" +
str(i+1), inst[i]));
2760 std::stringstream ret;
2763 std::istringstream stream(src);
2765 bool filter_macros =
true;
2769 std::string active_symbol;
2771 while (std::getline(stream, line)) {
2775 if (line.find(
"template")==0)
continue;
2778 if (filter_macros && line.find(
"#define")==0)
continue;
2779 if (filter_macros && line.find(
"#undef")==0)
continue;
2782 if (line.find(
"casadi_assert") != std::string::npos)
continue;
2783 if (line.find(
"casadi_error") != std::string::npos)
continue;
2784 if (line.find(
"casadi_message") != std::string::npos)
continue;
2787 if (line ==
"inline")
continue;
2790 if (line.find(
"// SYMBOL") != std::string::npos) {
2791 n1 = line.find(
"\"");
2792 n2 = line.find(
"\"", n1+1);
2793 std::string sym = line.substr(n1+1, n2-n1-1);
2796 rep.push_back(std::make_pair(sym, sym +
suffix));
2798 active_symbol =
"casadi_" + sym;
2803 if (line.find(
"// C-REPLACE") != std::string::npos) {
2805 size_t pos = line.find(
"// C-REPLACE");
2809 rep.push_back(std::make_pair(key, sub));
2814 if (!
verbose_runtime && line.find(
"// C-VERBOSE") != std::string::npos) {
2816 std::getline(stream, line);
2820 if (line.find(
"// FILTER-MACROS ON") != std::string::npos) {
2821 filter_macros =
true;
2824 if (line.find(
"// FILTER-MACROS OFF") != std::string::npos) {
2825 filter_macros =
false;
2829 n1 = line.find(
"//");
2830 if (n1 != std::string::npos) line.erase(n1);
2833 n1 = line.find_last_not_of(
' ');
2834 if (n1 != std::string::npos) {
2841 if (!active_symbol.empty() &&
2842 line.find(active_symbol +
"(") != std::string::npos) {
2843 std::string sig_prefix;
2844 if (this->
static_aux) sig_prefix +=
"static ";
2845 if (this->
inline_aux) sig_prefix +=
"inline ";
2846 if (!sig_prefix.empty()) line = sig_prefix + line;
2847 active_symbol.clear();
2851 for (
auto&& it = rep.rbegin(); it!=rep.rend(); ++it) {
2852 line =
replace(line, it->first, it->second);
2856 ret << line <<
"\n";
2866 *
this <<
"/* " << s <<
" */\n";
2872 const std::vector<Sparsity>& sp_in,
2873 const std::vector<Sparsity>& sp_out) {
2878 *
this <<
declare(
"const casadi_int* " +
name +
"_sparsity_in(casadi_int i)") <<
" {\n"
2879 <<
"switch (i) {\n";
2880 for (casadi_int i=0; i<sp_in.size(); ++i) {
2883 *
this <<
"default: return 0;\n}\n"
2887 *
this <<
declare(
"const casadi_int* " +
name +
"_sparsity_out(casadi_int i)") <<
" {\n"
2888 <<
"switch (i) {\n";
2889 for (casadi_int i=0; i<sp_out.size(); ++i) {
2892 *
this <<
"default: return 0;\n}\n"
2897 qr(
const std::string& sp,
const std::string& A,
const std::string& w,
2898 const std::string& sp_v,
const std::string& v,
const std::string& sp_r,
2899 const std::string& r,
const std::string& beta,
const std::string& prinv,
2900 const std::string& pc) {
2902 return "casadi_qr(" + sp +
", " + A +
", " + w +
", "
2903 + sp_v +
", " + v +
", " + sp_r +
", " + r +
", "
2904 + beta +
", " + prinv +
", " + pc +
");";
2908 det(
const std::string& sp_v,
const std::string& v,
2909 const std::string& sp_r,
const std::string& r,
const std::string& beta) {
2911 return "casadi_det(" + sp_v +
", " + v +
", " + sp_r +
", " + r +
", " + beta +
")";
2915 qr_solve(
const std::string& x, casadi_int nrhs,
bool tr,
2916 const std::string& sp_v,
const std::string& v,
2917 const std::string& sp_r,
const std::string& r,
2918 const std::string& beta,
const std::string& prinv,
2919 const std::string& pc,
const std::string& w) {
2921 return "casadi_qr_solve(" + x +
", " +
str(nrhs) +
", " + (tr ?
"1" :
"0") +
", "
2922 + sp_v +
", " + v +
", " + sp_r +
", " + r +
", "
2923 + beta +
", " + prinv +
", " + pc +
", " + w +
");";
2927 lsqr_solve(
const std::string& A,
const std::string&x,
2928 casadi_int nrhs,
bool tr,
const std::string& sp,
const std::string& w) {
2930 return "casadi_lsqr_solve(" + A +
", " + x +
", " +
str(nrhs) +
", "
2931 + (tr ?
"1" :
"0") +
", " + sp +
", " + w +
");";
2935 ldl(
const std::string& sp_a,
const std::string& a,
2936 const std::string& sp_lt,
const std::string& lt,
const std::string& d,
2937 const std::string& p,
const std::string& w) {
2939 return "casadi_ldl(" + sp_a +
", " + a +
", " + sp_lt +
", " + lt +
", "
2940 + d +
", " + p +
", " + w +
");";
2944 ldl_solve(
const std::string& x, casadi_int nrhs,
2945 const std::string& sp_lt,
const std::string& lt,
const std::string& d,
2946 const std::string& p,
const std::string& w) {
2948 return "casadi_ldl_solve(" + x +
", " +
str(nrhs) +
", " + sp_lt +
", "
2949 + lt +
", " + d +
", " + p +
", " + w +
");";
2953 fmax(
const std::string& x,
const std::string& y) {
2955 return "casadi_fmax(" + x +
", " + y +
");";
2959 fmin(
const std::string& x,
const std::string& y) {
2961 return "casadi_fmin(" + x +
", " + y +
");";
2965 vfmax(
const std::string& x, casadi_int n,
const std::string& y) {
2967 return "casadi_vfmax(" + x +
", " +
str(n) +
", " + y +
");";
2971 vfmin(
const std::string& x, casadi_int n,
const std::string& y) {
2973 return "casadi_vfmin(" + x +
", " +
str(n) +
", " + y +
");";
2977 vfmax(
const std::string& x,
const std::string& n,
const std::string& y) {
2979 return "casadi_vfmax(" + x +
", " + n +
", " + y +
");";
2983 vfmin(
const std::string& x,
const std::string& n,
const std::string& y) {
2985 return "casadi_vfmin(" + x +
", " + n +
", " + y +
");";
2989 max(
const std::string& x,
const std::string& y) {
2991 return "casadi_max(" + x +
", " + y +
")";
2995 min(
const std::string& x,
const std::string& y) {
2997 return "casadi_min(" + x +
", " + y +
")";
3001 mmax(
const std::string& x, casadi_int n,
bool is_dense) {
3003 return "casadi_mmax(" + x +
", " +
str(n) +
", " +
str(casadi_int(is_dense)) +
")";
3007 mmin(
const std::string& x, casadi_int n,
bool is_dense) {
3009 return "casadi_mmin(" + x +
", " +
str(n) +
", " +
str(casadi_int(is_dense)) +
")";
3013 max_viol(casadi_int n,
const std::string& x,
const std::string& lb,
const std::string& ub) {
3015 return "casadi_max_viol(" +
str(n) +
", " + x+
", " + lb +
", " + ub +
")";
3019 sum_viol(casadi_int n,
const std::string& x,
const std::string& lb,
const std::string& ub) {
3021 return "casadi_sum_viol(" +
str(n) +
", " + x+
", " + lb +
", " + ub +
")";
3025 norm_inf(casadi_int n,
const std::string& x) {
3027 return "casadi_norm_inf(" +
str(n) +
", " + x +
")";
3031 norm_1(casadi_int n,
const std::string& x) {
3033 return "casadi_norm_1(" +
str(n) +
", " + x +
")";
3037 norm_2(casadi_int n,
const std::string& x) {
3039 return "casadi_norm_2(" +
str(n) +
", " + x +
")";
3045 return "casadi_lb_eig(" +
sparsity(sp_h) +
", " + h +
")";
3051 return "casadi_regularize(" +
sparsity(sp_h) +
", " + h +
", " + reg +
");";
3056 const std::string& Hin,
const std::string& Hout,
const std::string& iw,
const std::string& w) {
3062 low(
const std::string& x,
const std::string& grid, casadi_int ng, casadi_int lookup_mode) {
3064 return "casadi_low(" + x +
", " + grid +
", " +
str(ng) +
", " +
str(lookup_mode) +
");";
3069 const std::string& lam,
const std::string& lbx,
const std::string& ubx) {
3071 return "casadi_bound_consistency(" +
str(n) +
", " + x +
", " + lam +
3072 ", " + lbx +
", " + ubx +
")";
3076 file_slurp(
const std::string& fname, casadi_int n,
const std::string& a) {
3078 return "casadi_file_slurp(\"" + fname +
"\", " +
str(n) +
", " + a +
")";
3082 to_file(
const std::string& f,
const Sparsity& sp,
const std::string& x) {
3084 return "casadi_to_file(" + f +
", " +
sparsity(sp) +
", " + x +
")";
3089 casadi_int n = is_input ? f.
n_in() : f.
n_out();
3093 if (!effective_dir.empty())
prefix = effective_dir +
"/";
3094 std::string inout = is_input ?
"in" :
"out";
3100 "Unable to create the required directory for '" + dir +
"'.");
3105 for (casadi_int i = 0; i < n; ++i) {
3108 std::string fixed_part =
prefix + f.
name() +
"." + inout +
"." + io_name +
"." + dump_format;
3109 casadi_int buf_size = fixed_part.size() + 1 + 6 + 1;
3111 *
this <<
"char dump_fname[" << buf_size <<
"];\n";
3112 *
this <<
"FILE* dump_file;\n";
3113 *
this <<
"snprintf(dump_fname, " << buf_size <<
", \""
3114 <<
prefix << f.
name() <<
".%06d." << inout <<
"." << io_name
3115 <<
"." << dump_format <<
"\", dump_id_local);\n";
3117 *
this <<
printf(
"dump -> %s\\n",
"dump_fname") <<
"\n";
3119 *
this <<
"dump_file = fopen(dump_fname, \"w\");\n";
3120 *
this <<
"if (dump_file) {\n";
3121 *
this <<
to_file(
"dump_file", sp, arr +
"[" +
str(i) +
"]") <<
";\n";
3122 *
this <<
"fclose(dump_file);\n";
3129 std::string fixed_part =
prefix + f.
name() +
"." + inout +
".txt";
3130 casadi_int buf_size = fixed_part.size() + 1 + 6 + 1;
3132 *
this <<
"char dump_fname[" << buf_size <<
"];\n";
3133 *
this <<
"FILE* dump_file;\n";
3134 *
this <<
"casadi_int dump_k;\n";
3135 *
this <<
"snprintf(dump_fname, " << buf_size <<
", \""
3136 <<
prefix << f.
name() <<
".%06d." << inout <<
".txt\", dump_id_local);\n";
3137 *
this <<
"dump_file = fopen(dump_fname, \"w\");\n";
3138 *
this <<
"if (dump_file) {\n";
3139 for (casadi_int i = 0; i < n; ++i) {
3141 casadi_int nnz = sp.
nnz();
3142 std::string a = arr +
"[" +
str(i) +
"]";
3144 *
this <<
"if (" << a <<
") {\n";
3146 *
this <<
"fprintf(dump_file, \"\\n\");\n";
3147 *
this <<
"} else {\n";
3148 std::string zero_str = is_input ?
"0.0000000000000000e+00" :
"nan";
3149 *
this <<
"for (dump_k=0; dump_k<" << nnz <<
"; ++dump_k) "
3150 <<
"fprintf(dump_file, \"" << zero_str <<
"\\n\");\n";
3154 *
this <<
"fclose(dump_file);\n";
3162 casadi_int n = is_input ? f.
n_in() : f.
n_out();
3163 std::string inout = is_input ?
"Input" :
"Output";
3165 *
this <<
printf(
"Function " + f.
name() +
"\\n") <<
"\n";
3166 for (casadi_int i = 0; i < n; ++i) {
3169 *
this <<
printf(inout +
" " +
str(i) +
" (" + io_name +
"): ") <<
"\n";
3171 *
this <<
printf(
"\\n") <<
"\n";
3176 cache_check(
const std::string& key,
const std::string& cache,
const std::string& loc,
3177 casadi_int stride, casadi_int sz, casadi_int key_sz,
const std::string& val) {
3179 return "casadi_cache_check(" + key +
", " + cache +
", " + loc +
", " +
3180 str(stride) +
", " +
str(sz) +
", " +
str(key_sz) +
", " + val +
")";
3184 sz_arg = sz_res = sz_iw = sz_w = 0;
3186 sz_arg = std::max(sz_arg, f.f.sz_arg());
3187 sz_res = std::max(sz_res, f.f.sz_res());
3188 sz_iw = std::max(sz_iw, f.f.sz_iw());
3189 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.
void add_runtime(const std::string &key, const std::string &src, const std::vector< std::string > &inst)
Add a sanitized runtime source once per key.
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::set< std::string > added_runtimes_
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 the sparsity pattern of an output, by index or name.
FunctionInternal * get() const
const std::vector< std::string > & name_in() const
Get the names of all inputs, in order.
const std::string & name() const
Get the name given at construction ("null" for a null object)
static bool check_name(const std::string &name)
Check whether a string is a valid function name.
const Sparsity & sparsity_in(casadi_int ind) const
Get the sparsity pattern of an input, by index or 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 the sparsity patterns of all Jacobian blocks.
const std::vector< std::string > & name_out() const
Get the names of all outputs, in order.
static casadi_int copy_elision_min_size
bool verbose_
Verbose printout.
casadi_int nnz() const
Number of structural nonzeros.
std::vector< casadi_int > compress(bool canonical=true) const
Compact single-vector representation of the 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.