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);
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 
821  static std::string array(const std::string& type, const std::string& name, casadi_int len,
822  const std::string& def=std::string());
823 
827  void print_vector(std::ostream &s, const std::string& name,
828  const std::vector<casadi_int>& v);
829 
833  void print_vector(std::ostream &s, const std::string& name,
834  const std::vector<char>& v);
835 
839  void print_vector(std::ostream &s, const std::string& name,
840  const std::vector<double>& v);
841 
845  void print_vector(std::ostream &s, const std::string& name,
846  const std::vector<std::string>& v);
847 
851  std::string print_canonical(const Sparsity& sp, const std::string& arg);
852 
856  std::string print_vector(casadi_int sz, const std::string& arg);
857 
861  std::string print_scalar(const std::string& arg);
862 
866  std::string fprintf_scalar(const std::string& f, const std::string& arg);
867 
871  std::string fprintf_vector(const std::string& f, casadi_int sz,
872  const std::string& arg, const std::string& sep);
873 
877  std::string copy(const std::string& arg, std::size_t n, const std::string& res);
878  void copy_check(const std::string& arg, std::size_t n, const std::string& res,
879  bool check_lhs=true, bool check_rhs=true);
880  void copy_default(const std::string& arg, std::size_t n, const std::string& res,
881  const std::string& def, bool check_rhs=true);
882 
883  // Should we elide a copy?
884  bool elide_copy(casadi_int sz);
885 
889  std::string fill(const std::string& res, std::size_t n, const std::string& v);
890 
894  std::string clear(const std::string& res, std::size_t n);
895 
899  std::string arg(casadi_int i) const;
900 
904  std::string res(casadi_int i) const;
905 
909  std::string mem(const Function& f);
910 
914  std::string project(const std::string& arg, const Sparsity& sp_arg,
915  const std::string& res, const Sparsity& sp_res,
916  const std::string& w);
917 
921  std::string tri_project(const std::string& arg, const Sparsity& sp_arg,
922  const std::string& res, bool lower);
923 
927  std::string densify(const std::string& arg, const Sparsity& sp_arg,
928  const std::string& res, bool tr=false);
929 
933  std::string sparsify(const std::string& arg, const std::string& res,
934  const Sparsity& sp_res, bool tr=false);
935 
939  std::string to_mex(const Sparsity& sp, const std::string& arg);
940 
944  std::string from_mex(std::string& arg,
945  const std::string& res, std::size_t res_off, const Sparsity& sp_res,
946  const std::string& w);
947 
951  static std::string fmu_helpers(const std::string& modelname);
952 
956  std::string printf(const std::string& str,
957  const std::vector<std::string>& arg=std::vector<std::string>());
958  std::string printf(const std::string& str, const std::string& arg1);
959  std::string printf(const std::string& str, const std::string& arg1, const std::string& arg2);
960  std::string printf(const std::string& str, const std::string& arg1, const std::string& arg2,
961  const std::string& arg3);
962 
966  std::string print_op(casadi_int op, const std::string& a0);
967  std::string print_op(casadi_int op, const std::string& a0, const std::string& a1);
968 
972  std::string file_slurp(const std::string& fname, casadi_int n, const std::string& a);
973 
977  std::string to_file(const std::string& f, const Sparsity& sp, const std::string& x);
978 
982  void generate_dump(const Function& f, const std::string& arr, bool is_input);
983 
987  void generate_print(const Function& f, const std::string& arr, bool is_input);
988 
992  std::string cache_check(const std::string& key, const std::string& cache,
993  const std::string& loc, casadi_int stride, casadi_int sz, casadi_int key_sz,
994  const std::string& val);
995 
997  static std::string casadi_version();
998 
1000  static void stream_open(std::ostream& f, bool cpp);
1001 
1003  static void stream_close(std::ostream& f, bool cpp);
1004 
1008  void sz_work(size_t& sz_arg, size_t& sz_res, size_t& sz_iw, size_t& sz_w) const;
1009 
1010  private:
1011 
1012  // Generate casadi_real definition
1013  void generate_casadi_real(std::ostream &s) const;
1014 
1015  // Generate casadi_int definition
1016  void generate_casadi_int(std::ostream &s) const;
1017 
1018  // Generate mex entry point
1019  void generate_mex(std::ostream &s) const;
1020 
1021  // Generate function specific code for Simulink s-Function
1022  std::string codegen_sfunction(const Function& f) const;
1023 
1024  // Export s-Function to file
1025  void generate_sfunction(const std::string& name, const std::string& sfunction) const;
1026 
1027  // Generate main entry point
1028  void generate_main(std::ostream &s) const;
1029 
1030  // Generate export symbol macros
1031  void generate_export_symbol(std::ostream &s) const;
1032 
1033  // Generate import symbol macros
1034  void generate_import_symbol(std::ostream &s) const;
1035 
1036  // private:
1037  public:
1039 
1040  // Name of generated file
1041  std::string name, suffix;
1042 
1043  // Real-type used for the codegen
1044  std::string casadi_real_type;
1045 
1046  // Int-type used for the codegen
1047  std::string casadi_int_type;
1048 
1049  // Should we create a memory entry point?
1050  bool with_mem;
1051 
1052  // Generate header file?
1053  bool with_header;
1054 
1055  // Are we creating a MEX file?
1056  bool mex;
1057 
1058  // Are we creating a s-function?
1059  bool with_sfunction;
1060  std::vector<std::string> added_sfunctions;
1061 
1062  // Unroll arguments?
1063  bool unroll_args;
1064 
1065  // Emit runtime auxiliary functions with 'static' storage class?
1066  bool static_aux;
1067 
1068  // Emit runtime auxiliary functions with 'inline' hint?
1069  bool inline_aux;
1070 
1071  // Verbose codegen?
1072  bool verbose;
1073 
1074  // Verbose runtime?
1075  bool verbose_runtime;
1076 
1077  // Are we generating C++?
1078  bool cpp;
1079 
1080  // Should we generate a main (allowing evaluation from command line)
1081  bool main;
1082 
1083  // Should we include mayth library?
1084  bool include_math;
1085 
1086  // Do we want to be lean on stack usage?
1087  bool avoid_stack_;
1088 
1089  std::string infinity, nan, real_min;
1090 
1097  bool codegen_scalars;
1098 
1099  // Have a flag for exporting/importing symbols
1100  bool with_export, with_import;
1101 
1102  // Maximum number of declarations per line
1103  casadi_int max_declarations_per_line;
1104 
1105  // Maximum number of initializer elements per line
1106  casadi_int max_initializer_elements_per_line;
1107 
1108  // Force the external API to use canonical sparsity
1109  bool force_canonical;
1110 
1111  // Route L1 ops (axpy/dot/scal/norm_1/norm_2) through the active BLAS
1112  // plugin in generated code; off => built-in reference kernels.
1113  bool l1_blas;
1114 
1115  // Emit thread-safe checkout/release?
1116  bool thread_safe_;
1117 
1118  // Prefix symbols in DLLs?
1119  std::string dll_export, dll_import;
1120 
1121  // Prefix
1122  std::string prefix;
1123 
1124  // Prefix/suffix for dump directory in codegen
1125  std::string dump_dir_prefix;
1126  std::string dump_dir_suffix;
1127 
1128  // std::stringstreams holding the different parts of the file being generated
1129  std::stringstream includes;
1130  std::stringstream auxiliaries;
1131  std::stringstream body;
1132  std::stringstream header;
1133  std::stringstream buffer;
1134 
1135  // Are we at a new line?
1136  bool newline_;
1137 
1138  // Indentation
1139  casadi_int indent_;
1140  casadi_int current_indent_;
1141 
1142  // Number of zeros/ones
1143  casadi_int sz_zeros_;
1144  casadi_int sz_ones_;
1145 
1146  casadi_int padding_length_;
1147 
1148  // Names of exposed functions
1149  std::vector<std::string> exposed_fname;
1150 
1151  // Code generated sparsities
1152  std::set<std::string> sparsity_meta;
1153 
1154  // Set of already included header files
1155  std::set<std::string> added_includes_;
1156  std::set<std::string> added_externals_;
1157  std::set<std::string> added_shorthands_;
1158  std::multimap<Auxiliary, std::vector<std::string>> added_auxiliaries_;
1159  std::multimap<size_t, size_t> added_double_constants_;
1160  std::multimap<size_t, size_t> added_integer_constants_;
1161  std::multimap<size_t, size_t> added_char_constants_;
1162  std::multimap<size_t, size_t> added_string_constants_;
1163  std::map<std::string, std::pair<std::string, std::string> > local_variables_;
1164  std::vector<std::string> local_cleanup_;
1165  bool local_void_;
1166  std::map<std::string, std::string> local_default_;
1167  std::map<const void *, casadi_int> file_scope_double_;
1168  std::map<const void *, casadi_int> file_scope_integer_;
1169  std::vector< std::vector<double> > pool_double_defaults_;
1170  std::map<std::string, casadi_int> pool_double_;
1171  std::map<const FunctionInternal*, std::set<std::string> > local_mutexes_;
1172 
1173  // Added functions
1174  struct FunctionMeta {
1175  // The function object
1176  Function f;
1177  // Name in codegen
1178  std::string codegen_name;
1179  };
1180  std::vector<FunctionMeta> added_functions_;
1181 
1182  // Counters for creating unique identifiers
1183  std::map<std::string, std::map<FunctionInternal*, casadi_int> > added_wrappers_;
1184 
1185  // Constants
1186  std::vector<std::vector<double> > double_constants_;
1187  std::vector<std::vector<casadi_int> > integer_constants_;
1188  std::vector<std::vector<char> > char_constants_;
1189  std::vector<std::vector<std::string> > string_constants_;
1190 
1191  // Does any function need thread-local memory?
1192  bool needs_mem_;
1193 
1194  // Hash a vector
1195  static size_t hash(const std::vector<double>& v);
1196  static size_t hash(const std::vector<casadi_int>& v);
1197  static size_t hash(const std::vector<char>& v);
1198  static size_t hash(const std::vector<std::string>& v);
1199 
1200  std::string wrapper(const Function& base, const std::string& name);
1201 
1202  // Compare two vectors
1203  template<typename T>
1204  static bool equal(const std::vector<T>& v1, const std::vector<T>& v2) {
1205  if (v1.size()!=v2.size()) return false;
1206  for (casadi_int j=0; j<v1.size(); ++j) {
1207  if (v1[j]!=v2[j]) return false;
1208  }
1209  return true;
1210  }
1212 #endif // SWIG
1213  };
1214 
1215 
1216 } // namespace casadi
1217 
1218 #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.