code_generator.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_CODE_GENERATOR_HPP
27 #define CASADI_CODE_GENERATOR_HPP
28 
29 #include "function.hpp"
30 
31 #include <map>
32 #include <set>
33 #include <sstream>
34 #include <type_traits>
35 
36 namespace casadi {
37 
44  class CASADI_EXPORT CodeGenerator {
45  public:
47  CodeGenerator(const std::string& name, const Dict& opts = Dict());
48 
50  void add(const Function& f, bool with_jac_sparsity=false);
51 
52 #ifndef SWIG
54  void dump(std::ostream& s);
55 #endif // SWIG
56 
58  std::string dump();
59 
67  std::string generate(const std::string& prefix="");
68 
70  void add_include(const std::string& new_include, bool relative_path=false,
71  const std::string& use_ifdef=std::string());
72 
73 #ifndef SWIG
75  std::string add_dependency(const Function& f);
76 
78  void add_external(const std::string& new_external, const std::string& name="");
79 
81  std::string shorthand(const std::string& name) const;
82 
84  std::string shorthand(const std::string& name, bool allow_adding=true);
85 
86  /* Add a sparsity pattern
87  *
88  * \param canonical If true, request canonical form,
89  * as opposed to potential dense abbreviation
90  */
91  std::string sparsity(const Sparsity& sp, bool canonical=true);
92 
93  /* Add a sparsity pattern, get index
94  *
95  * \param canonical If true, request canonical form,
96  * as opposed to potential dense abbreviation
97  */
98  casadi_int add_sparsity(const Sparsity& sp, bool canonical=true);
99 
103  casadi_int get_sparsity(const Sparsity& sp) const;
104 
108  casadi_int get_constant(const std::vector<double>& v, bool allow_adding=false);
109 
113  casadi_int get_constant(const std::vector<casadi_int>& v, bool allow_adding=false);
114 
118  casadi_int get_constant(const std::vector<char>& v, bool allow_adding=false);
119 
123  casadi_int get_constant(const std::vector<std::string>& v, bool allow_adding=false);
124 
128  std::string constant(const std::vector<casadi_int>& v);
129 
133  std::string constant(const std::vector<int>& v) {
134  return constant(vector_static_cast<casadi_int>(v));
135  }
136 
140  void constant_copy(
141  const std::string& var_name,
142  const std::vector<casadi_int>& v,
143  const std::string& type="casadi_int");
144 
148  std::string constant(const std::vector<double>& v);
149 
153  std::string constant(const std::vector<char>& v);
154 
158  std::string constant(const std::vector<std::string>& v);
159 
163  void define_rom_double(const void* id, casadi_int size);
164 
168  std::string rom_double(const void* id) const;
169 
173  void define_rom_integer(const void* id, casadi_int size);
174 
178  std::string rom_integer(const void* id) const;
179 
183  void define_pool_double(const std::string& name, const std::vector<double>& def);
184 
188  std::string pool_double(const std::string& name) const;
189 
195  void define_local_mutex(const Function& f, const std::string& name);
196 
200  std::string local_mutex(const Function& f, const std::string& name) const;
201 
205  const std::set<std::string>& local_mutexes(const Function& f) const;
206 
210  void setup_callback(const std::string& s, const Function& f);
211 
215  std::string operator()(const Function& f, const std::string& arg,
216  const std::string& res, const std::string& iw,
217  const std::string& w, const std::string& failure_ret="1");
218 
222  CodeGenerator& operator<<(const std::string& s);
223 
227  void print_formatted(const std::string& s);
228 
232  template<typename T>
233  CodeGenerator& operator<<(T s) {
234  std::stringstream ss;
235  ss << s;
236  return (*this) << ss.str();
237  }
238 
242  void flush(std::ostream &s);
243 
247  void local(const std::string& name, const std::string& type, const std::string& ref="");
248 
252  void scope_enter();
253 
257  void scope_exit();
258 
264  void scope_return(const std::string& value);
265 
271  void scope_return();
272 
276  void scope_add_cleanup(const std::string& code);
277 
281  std::string sx_work(casadi_int i);
282 
286  void init_local(const std::string& name, const std::string& def);
287 
291  void indent() {current_indent_++;}
292 
296  void unindent() {current_indent_--;}
297 
301  bool avoid_stack() const { return avoid_stack_;}
302 
306  bool thread_safe() const { return thread_safe_; }
307 
311  std::string constant(double v);
312  std::string constant(casadi_int v);
313  std::string constant(const std::string& v);
314  std::string constant(char v);
315 
316  std::string format_padded(casadi_int i) const;
317 
318  std::string zeros(casadi_int sz);
319  std::string ones(casadi_int sz);
320 
324  template <typename T>
325  std::string initializer(const std::vector<T>& v) {
326  std::stringstream s;
327  if (v.size() > max_initializer_elements_per_line) {
328  s << "\n ";
329  }
330 
331  s << "{";
332  // Shortcut only for arithmetic T; for std::string, `T(0)` would
333  // invoke std::string(const char*) with a null pointer.
334  bool all_zeros = std::is_arithmetic<T>::value && v.size() > 0;
335  if (all_zeros) {
336  for (const auto& el : v) {
337  if (el != T()) {
338  all_zeros = false;
339  break;
340  }
341  }
342  }
343  if (all_zeros) {
344  s << constant(T()); // empty_initialization shorthand
345  } else {
346  for (casadi_int i = 0; i < v.size(); ++i) {
347  if (i != 0) {
348  if (max_initializer_elements_per_line > 1 &&
349  i % max_initializer_elements_per_line == 0) {
350  s << ",\n ";
351  } else {
352  s << ", ";
353  }
354  }
355  s << constant(v[i]);
356  }
357  }
358  s << "}";
359  return s.str();
360  }
361 
365  std::string sanitize_source(const std::string& src,
366  const std::vector<std::string>& inst,
367  bool add_shorthand=true);
368 
372  std::string dot(casadi_int n, const std::string& x, const std::string& y);
373 
377  std::string mv(const std::string& x, const Sparsity& sp_x,
378  const std::string& y, const std::string& z, bool tr);
379 
383  std::string mv(const std::string& x, casadi_int nrow_x, casadi_int ncol_x,
384  const std::string& y, const std::string& z, bool tr);
385 
389  std::string axpy(casadi_int n, const std::string& a,
390  const std::string& x, const std::string& y);
391 
397  std::string clip_min(const std::string& x, casadi_int n,
398  const std::string& min, const std::string& mask);
399 
405  std::string clip_max(const std::string& x, casadi_int n,
406  const std::string& min, const std::string& mask);
407 
412  std::string vector_fmax(casadi_int n, const std::string& x,
413  const std::string& y, const std::string& z);
414 
419  std::string vector_fmin(casadi_int n, const std::string& x,
420  const std::string& y, const std::string& z);
421 
426  std::string masked_norm_inf(casadi_int n, const std::string& x,
427  const std::string& mask);
428 
429 
433  std::string scal(casadi_int n, const std::string& alpha, const std::string& x);
434 
438  std::string mtimes(const std::string& x, const Sparsity& sp_x,
439  const std::string& y, const Sparsity& sp_y,
440  const std::string& z, const Sparsity& sp_z,
441  const std::string& w, bool tr);
442 
446  std::string mtimes(const std::string& x, casadi_int nrow_x, casadi_int ncol_x,
447  const std::string& y, casadi_int ncol_y,
448  const std::string& z, bool tr);
449 
453  std::string mtimes_dense_sparse(const std::string& x, casadi_int nrow_x,
454  const std::string& y, const Sparsity& sp_y,
455  const std::string& z);
456 
460  std::string trilsolve(const Sparsity& sp_x, const std::string& x, const std::string& y,
461  bool tr, bool unity, casadi_int nrhs);
462 
466  std::string triusolve(const Sparsity& sp_x, const std::string& x, const std::string& y,
467  bool tr, bool unity, casadi_int nrhs);
468 
472  std::string bilin(const std::string& A, const Sparsity& sp_A,
473  const std::string& x, const std::string& y);
474 
478  std::string rank1(const std::string& A, const Sparsity& sp_A, const std::string& alpha,
479  const std::string& x, const std::string& y);
480 
482  std::string logsumexp(const std::string& A, casadi_int n);
483 
487  std::string interpn(const std::string& res, casadi_int ndim, const std::string& grid,
488  const std::string& offset,
489  const std::string& values, const std::string& x,
490  const std::string& lookup_mode, casadi_int m,
491  const std::string& iw, const std::string& w);
492 
496  std::string interpn_grad(const std::string& grad,
497  casadi_int ndim, const std::string& grid,
498  const std::string& offset,
499  const std::string& values, const std::string& x,
500  const std::string& lookup_mode, casadi_int m,
501  const std::string& iw, const std::string& w);
502 
506  std::string trans(const std::string& x, const Sparsity& sp_x,
507  const std::string& y, const Sparsity& sp_y, const std::string& iw);
508 
512  std::string qr(const std::string& sp, const std::string& A,
513  const std::string& w, const std::string& sp_v,
514  const std::string& v, const std::string& sp_r,
515  const std::string& r, const std::string& beta,
516  const std::string& prinv, const std::string& pc);
517 
521  std::string det(const std::string& sp_v, const std::string& v,
522  const std::string& sp_r, const std::string& r, const std::string& beta);
523 
527  std::string qr_solve(const std::string& x, casadi_int nrhs, bool tr,
528  const std::string& sp_v, const std::string& v,
529  const std::string& sp_r, const std::string& r,
530  const std::string& beta, const std::string& prinv,
531  const std::string& pc, const std::string& w);
532 
536  std::string lsqr_solve(const std::string& A, const std::string&x,
537  casadi_int nrhs, bool tr, const std::string& sp, const std::string& w);
538 
542  std::string ldl(const std::string& sp_a, const std::string& a,
543  const std::string& sp_lt, const std::string& lt,
544  const std::string& d, const std::string& p,
545  const std::string& w);
546 
550  std::string ldl_solve(const std::string& x, casadi_int nrhs,
551  const std::string& sp_lt, const std::string& lt,
552  const std::string& d, const std::string& p,
553  const std::string& w);
554 
558  std::string fmax(const std::string& x, const std::string& y);
559 
563  std::string fmin(const std::string& x, const std::string& y);
564 
568  std::string mmax(const std::string& x, casadi_int n, bool is_dense);
569 
573  std::string mmin(const std::string& x, casadi_int n, bool is_dense);
574 
578  std::string vfmax(const std::string& x, casadi_int n, const std::string& y);
579 
583  std::string vfmin(const std::string& x, casadi_int n, const std::string& y);
584 
588  std::string vfmax(const std::string& x, const std::string& n, const std::string& y);
589 
593  std::string vfmin(const std::string& x, const std::string& n, const std::string& y);
594 
598  std::string max(const std::string& x, const std::string& y);
599 
603  std::string min(const std::string& x, const std::string& y);
604 
608  std::string norm_inf(casadi_int n, const std::string& x);
609 
613  std::string norm_1(casadi_int n, const std::string& x);
614 
620  std::string norm_2(casadi_int n, const std::string& x);
621 
625  std::string max_viol(casadi_int n, const std::string& x,
626  const std::string& lb, const std::string& ub);
627 
631  std::string sum_viol(casadi_int n, const std::string& x,
632  const std::string& lb, const std::string& ub);
633 
637  std::string bound_consistency(casadi_int n, const std::string& x,
638  const std::string& lam, const std::string& lbx, const std::string& ubx);
639 
643  std::string lb_eig(const Sparsity& sp_h, const std::string& h);
644 
648  std::string regularize(const Sparsity& sp_h, const std::string& h, const std::string& reg);
649 
653  std::string convexify_eval(const ConvexifyData& d,
654  const std::string& Hin, const std::string& Hout, const std::string& iw, const std::string& w);
655 
659  std::string low(const std::string& x, const std::string& grid,
660  casadi_int ng, casadi_int lookup_mode);
661 
665  std::string declare(std::string s);
666 
670  void comment(const std::string& s);
671 
675  enum Auxiliary {
676  AUX_COPY,
677  AUX_CVX,
678  AUX_CONVEXIFY,
679  AUX_SWAP,
680  AUX_SCAL,
681  AUX_AXPY,
682  AUX_DOT,
683  AUX_BILIN,
684  AUX_KRON,
685  AUX_KRON_DENSE,
686  AUX_KRON_DENSE_SPARSE,
687  AUX_KRON_SPARSE_DENSE,
688  AUX_KRON_CONTRACT_INNER,
689  AUX_KRON_CONTRACT_INNER_DENSE,
690  AUX_KRON_CONTRACT_INNER_DENSE_SPARSE,
691  AUX_KRON_CONTRACT_INNER_SPARSE_DENSE,
692  AUX_KRON_CONTRACT_OUTER,
693  AUX_KRON_CONTRACT_OUTER_DENSE,
694  AUX_KRON_CONTRACT_OUTER_DENSE_SPARSE,
695  AUX_KRON_CONTRACT_OUTER_SPARSE_DENSE,
696  AUX_RANK1,
697  AUX_NORM_1,
698  AUX_NORM_2,
699  AUX_CLIP_MAX,
700  AUX_CLIP_MIN,
701  AUX_VECTOR_FMAX,
702  AUX_VECTOR_FMIN,
703  AUX_NORM_INF,
704  AUX_MASKED_NORM_INF,
705  AUX_IAMAX,
706  AUX_CLEAR,
707  AUX_FILL,
708  AUX_MV,
709  AUX_MV_DENSE,
710  AUX_MTIMES,
711  AUX_MTIMES_DENSE,
712  AUX_MTIMES_DENSE_SPARSE,
713  AUX_TRILSOLVE,
714  AUX_TRIUSOLVE,
715  AUX_PROJECT,
716  AUX_TRI_PROJECT,
717  AUX_DENSIFY,
718  AUX_SPARSIFY,
719  AUX_TRANS,
720  AUX_TO_MEX,
721  AUX_FROM_MEX,
722  AUX_INTERPN,
723  AUX_INTERPN_GRAD,
724  AUX_FLIP,
725  AUX_INTERPN_WEIGHTS,
726  AUX_LOW,
727  AUX_INTERPN_INTERPOLATE,
728  AUX_DE_BOOR,
729  AUX_TENSOR_TTV,
730  AUX_ND_BOOR_EVAL,
731  AUX_FINITE_DIFF,
732  AUX_QR,
733  AUX_DET,
734  AUX_QP,
735  AUX_QRQP,
736  AUX_SOCP,
737  AUX_NLP,
738  AUX_SQPMETHOD,
739  AUX_FEASIBLESQPMETHOD,
740  AUX_LDL,
741  AUX_NEWTON,
742  AUX_TO_DOUBLE,
743  AUX_TO_INT,
744  AUX_CAST,
745  AUX_SQ,
746  AUX_SIGN,
747  AUX_IF_ELSE,
748  AUX_PRINTF,
749  AUX_FMIN,
750  AUX_FMAX,
751  AUX_FABS,
752  AUX_MIN,
753  AUX_MAX,
754  AUX_VFMIN,
755  AUX_VFMAX,
756  AUX_MAX_VIOL,
757  AUX_SUM_VIOL,
758  AUX_SUM,
759  AUX_REGULARIZE,
760  AUX_INF,
761  AUX_NAN,
762  AUX_REAL_MIN,
763  AUX_ISINF,
764  AUX_ISFINITE,
765  AUX_BOUNDS_CONSISTENCY,
766  AUX_LSQR,
767  AUX_FILE_SLURP,
768  AUX_CACHE,
769  AUX_LOG1P,
770  AUX_EXPM1,
771  AUX_HYPOT,
772  AUX_MMIN,
773  AUX_MMAX,
774  AUX_LOGSUMEXP,
775  AUX_SPARSITY,
776  AUX_BFGS,
777  AUX_ORACLE_CALLBACK,
778  AUX_OCP_BLOCK,
779  AUX_ORACLE,
780  AUX_SCALED_COPY,
781  AUX_BLAZING_COMMON,
782  AUX_BLAZING_1D_BOOR_EVAL,
783  AUX_BLAZING_2D_BOOR_EVAL,
784  AUX_BLAZING_3D_BOOR_EVAL,
785  AUX_BLAZING_4D_BOOR_EVAL,
786  AUX_BLAZING_5D_BOOR_EVAL,
787  AUX_PRINTME,
788  AUX_PRINT_SCALAR,
789  AUX_PRINT_VECTOR,
790  AUX_PRINT_CANONICAL,
791  AUX_FPRINTF_SCALAR,
792  AUX_FPRINTF_VECTOR,
793  AUX_TO_FILE,
794  AUX_THREADS
795  };
796 
800  void add_auxiliary(Auxiliary f, const std::vector<std::string>& inst = {"casadi_real"});
801 
805  void add_io_sparsities(const std::string& name,
806  const std::vector<Sparsity>& sp_in,
807  const std::vector<Sparsity>& sp_out);
808 
810  std::string work(casadi_int n, casadi_int sz, bool is_ref) const;
811 
813  std::string workel(casadi_int n) const;
814 
818  void reserve_work(casadi_int n);
819 
826  void set_codegen_sz_w(const FunctionInternal* f, size_t sz_w);
827 
833  bool get_codegen_sz_w(const FunctionInternal* f, size_t& sz_w) const;
834 
836  static std::string array(const std::string& type, const std::string& name, casadi_int len,
837  const std::string& def=std::string());
838 
842  void print_vector(std::ostream &s, const std::string& name,
843  const std::vector<casadi_int>& v);
844 
848  void print_vector(std::ostream &s, const std::string& name,
849  const std::vector<char>& v);
850 
854  void print_vector(std::ostream &s, const std::string& name,
855  const std::vector<double>& v);
856 
860  void print_vector(std::ostream &s, const std::string& name,
861  const std::vector<std::string>& v);
862 
866  std::string print_canonical(const Sparsity& sp, const std::string& arg);
867 
871  std::string print_vector(casadi_int sz, const std::string& arg);
872 
876  std::string print_scalar(const std::string& arg);
877 
881  std::string fprintf_scalar(const std::string& f, const std::string& arg);
882 
886  std::string fprintf_vector(const std::string& f, casadi_int sz,
887  const std::string& arg, const std::string& sep);
888 
892  std::string copy(const std::string& arg, std::size_t n, const std::string& res);
893  void copy_check(const std::string& arg, std::size_t n, const std::string& res,
894  bool check_lhs=true, bool check_rhs=true);
895  void copy_default(const std::string& arg, std::size_t n, const std::string& res,
896  const std::string& def, bool check_rhs=true);
897 
898  // Should we elide a copy?
899  bool elide_copy(casadi_int sz);
900 
904  std::string fill(const std::string& res, std::size_t n, const std::string& v);
905 
909  std::string clear(const std::string& res, std::size_t n);
910 
914  std::string arg(casadi_int i) const;
915 
919  std::string res(casadi_int i) const;
920 
924  std::string mem(const Function& f);
925 
929  std::string project(const std::string& arg, const Sparsity& sp_arg,
930  const std::string& res, const Sparsity& sp_res,
931  const std::string& w);
932 
936  std::string tri_project(const std::string& arg, const Sparsity& sp_arg,
937  const std::string& res, bool lower);
938 
942  std::string densify(const std::string& arg, const Sparsity& sp_arg,
943  const std::string& res, bool tr=false);
944 
948  std::string sparsify(const std::string& arg, const std::string& res,
949  const Sparsity& sp_res, bool tr=false);
950 
954  std::string to_mex(const Sparsity& sp, const std::string& arg);
955 
959  std::string from_mex(std::string& arg,
960  const std::string& res, std::size_t res_off, const Sparsity& sp_res,
961  const std::string& w);
962 
966  static std::string fmu_helpers(const std::string& modelname);
967 
971  std::string printf(const std::string& str,
972  const std::vector<std::string>& arg=std::vector<std::string>());
973  std::string printf(const std::string& str, const std::string& arg1);
974  std::string printf(const std::string& str, const std::string& arg1, const std::string& arg2);
975  std::string printf(const std::string& str, const std::string& arg1, const std::string& arg2,
976  const std::string& arg3);
977 
981  std::string print_op(casadi_int op, const std::string& a0);
982  std::string print_op(casadi_int op, const std::string& a0, const std::string& a1);
983 
987  std::string file_slurp(const std::string& fname, casadi_int n, const std::string& a);
988 
992  std::string to_file(const std::string& f, const Sparsity& sp, const std::string& x);
993 
997  void generate_dump(const Function& f, const std::string& arr, bool is_input);
998 
1002  void generate_print(const Function& f, const std::string& arr, bool is_input);
1003 
1007  std::string cache_check(const std::string& key, const std::string& cache,
1008  const std::string& loc, casadi_int stride, casadi_int sz, casadi_int key_sz,
1009  const std::string& val);
1010 
1012  static std::string casadi_version();
1013 
1015  static void stream_open(std::ostream& f, bool cpp);
1016 
1018  static void stream_close(std::ostream& f, bool cpp);
1019 
1023  void sz_work(size_t& sz_arg, size_t& sz_res, size_t& sz_iw, size_t& sz_w) const;
1024 
1025  private:
1026 
1027  // Generate casadi_real definition
1028  void generate_casadi_real(std::ostream &s) const;
1029 
1030  // Generate casadi_int definition
1031  void generate_casadi_int(std::ostream &s) const;
1032 
1033  // Generate mex entry point
1034  void generate_mex(std::ostream &s) const;
1035 
1036  // Generate function specific code for Simulink s-Function
1037  std::string codegen_sfunction(const Function& f) const;
1038 
1039  // Export s-Function to file
1040  void generate_sfunction(const std::string& name, const std::string& sfunction) const;
1041 
1042  // Generate main entry point
1043  void generate_main(std::ostream &s) const;
1044 
1045  // Generate export symbol macros
1046  void generate_export_symbol(std::ostream &s) const;
1047 
1048  // Generate import symbol macros
1049  void generate_import_symbol(std::ostream &s) const;
1050 
1051  // private:
1052  public:
1054 
1055  // Name of generated file
1056  std::string name, suffix;
1057 
1058  // Real-type used for the codegen
1059  std::string casadi_real_type;
1060 
1061  // Int-type used for the codegen
1062  std::string casadi_int_type;
1063 
1064  // Should we create a memory entry point?
1065  bool with_mem;
1066 
1067  // Generate header file?
1068  bool with_header;
1069 
1070  // Are we creating a MEX file?
1071  bool mex;
1072 
1073  // Are we creating a s-function?
1074  bool with_sfunction;
1075  std::vector<std::string> added_sfunctions;
1076 
1077  // Unroll arguments?
1078  bool unroll_args;
1079 
1080  // Emit runtime auxiliary functions with 'static' storage class?
1081  bool static_aux;
1082 
1083  // Emit runtime auxiliary functions with 'inline' hint?
1084  bool inline_aux;
1085 
1086  // Verbose codegen?
1087  bool verbose;
1088 
1089  // Verbose runtime?
1090  bool verbose_runtime;
1091 
1092  // Are we generating C++?
1093  bool cpp;
1094 
1095  // Should we generate a main (allowing evaluation from command line)
1096  bool main;
1097 
1098  // Should we include mayth library?
1099  bool include_math;
1100 
1101  // Do we want to be lean on stack usage?
1102  bool avoid_stack_;
1103 
1104  std::string infinity, nan, real_min;
1105 
1112  bool codegen_scalars;
1113 
1114  // Have a flag for exporting/importing symbols
1115  bool with_export, with_import;
1116 
1117  // Maximum number of declarations per line
1118  casadi_int max_declarations_per_line;
1119 
1120  // Maximum number of initializer elements per line
1121  casadi_int max_initializer_elements_per_line;
1122 
1123  // Force the external API to use canonical sparsity
1124  bool force_canonical;
1125 
1126  // Route L1 ops (axpy/dot/scal/norm_1/norm_2) through the active BLAS
1127  // plugin in generated code; off => built-in reference kernels.
1128  bool l1_blas;
1129 
1130  // Emit thread-safe checkout/release?
1131  bool thread_safe_;
1132 
1133  // Prefix symbols in DLLs?
1134  std::string dll_export, dll_import;
1135 
1136  // Prefix
1137  std::string prefix;
1138 
1139  // Prefix/suffix for dump directory in codegen
1140  std::string dump_dir_prefix;
1141  std::string dump_dir_suffix;
1142 
1143  // std::stringstreams holding the different parts of the file being generated
1144  std::stringstream includes;
1145  std::stringstream auxiliaries;
1146  std::stringstream body;
1147  std::stringstream header;
1148  std::stringstream buffer;
1149 
1150  // Are we at a new line?
1151  bool newline_;
1152 
1153  // Indentation
1154  casadi_int indent_;
1155  casadi_int current_indent_;
1156 
1157  // Number of zeros/ones
1158  casadi_int sz_zeros_;
1159  casadi_int sz_ones_;
1160 
1161  casadi_int padding_length_;
1162 
1163  // Names of exposed functions
1164  std::vector<std::string> exposed_fname;
1165 
1166  // Code generated sparsities
1167  std::set<std::string> sparsity_meta;
1168 
1169  // Set of already included header files
1170  std::set<std::string> added_includes_;
1171  std::set<std::string> added_externals_;
1172  std::set<std::string> external_names_;
1173  std::set<std::string> added_shorthands_;
1174  std::multimap<Auxiliary, std::vector<std::string>> added_auxiliaries_;
1175  std::multimap<size_t, size_t> added_double_constants_;
1176  std::multimap<size_t, size_t> added_integer_constants_;
1177  std::multimap<size_t, size_t> added_char_constants_;
1178  std::multimap<size_t, size_t> added_string_constants_;
1179  std::map<std::string, std::pair<std::string, std::string> > local_variables_;
1180  std::vector<std::string> local_cleanup_;
1181  bool local_void_;
1182  std::map<std::string, std::string> local_default_;
1183  std::map<const void *, casadi_int> file_scope_double_;
1184  std::map<const void *, casadi_int> file_scope_integer_;
1185  std::vector< std::vector<double> > pool_double_defaults_;
1186  std::map<std::string, casadi_int> pool_double_;
1187  std::map<const FunctionInternal*, std::set<std::string> > local_mutexes_;
1188 
1189  // Work vector sizes of generated function bodies, cf. set_codegen_sz_w
1190  std::map<const FunctionInternal*, size_t> codegen_sz_w_;
1191 
1192  // Added functions
1193  struct FunctionMeta {
1194  // The function object
1195  Function f;
1196  // Name in codegen
1197  std::string codegen_name;
1198  };
1199  std::vector<FunctionMeta> added_functions_;
1200 
1201  // Counters for creating unique identifiers
1202  std::map<std::string, std::map<FunctionInternal*, casadi_int> > added_wrappers_;
1203 
1204  // Constants
1205  std::vector<std::vector<double> > double_constants_;
1206  std::vector<std::vector<casadi_int> > integer_constants_;
1207  std::vector<std::vector<char> > char_constants_;
1208  std::vector<std::vector<std::string> > string_constants_;
1209 
1210  // Does any function need thread-local memory?
1211  bool needs_mem_;
1212 
1213  // Hash a vector
1214  static size_t hash(const std::vector<double>& v);
1215  static size_t hash(const std::vector<casadi_int>& v);
1216  static size_t hash(const std::vector<char>& v);
1217  static size_t hash(const std::vector<std::string>& v);
1218 
1219  std::string wrapper(const Function& base, const std::string& name);
1220 
1221  // Compare two vectors
1222  template<typename T>
1223  static bool equal(const std::vector<T>& v1, const std::vector<T>& v2) {
1224  if (v1.size()!=v2.size()) return false;
1225  for (casadi_int j=0; j<v1.size(); ++j) {
1226  if (v1[j]!=v2[j]) return false;
1227  }
1228  return true;
1229  }
1231 #endif // SWIG
1232  };
1233 
1234 
1235 } // namespace casadi
1236 
1237 #endif // CASADI_CODE_GENERATOR_HPP
Helper class for C code generation.
std::string dump()
Generate a file, return code as string.
void add(const Function &f, bool with_jac_sparsity=false)
Add a function (name generated)
CodeGenerator(const std::string &name, const Dict &opts=Dict())
Constructor.
std::string generate(const std::string &prefix="")
Generate file(s)
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 <....
Function object.
Definition: function.hpp:60
General sparsity class.
Definition: sparsity.hpp:106
The casadi namespace.
Definition: archiver.hpp:32
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.