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  void add_runtime(const std::string& key, const std::string& src,
373  const std::vector<std::string>& inst);
374 
378  std::string dot(casadi_int n, const std::string& x, const std::string& y);
379 
383  std::string mv(const std::string& x, const Sparsity& sp_x,
384  const std::string& y, const std::string& z, bool tr);
385 
389  std::string mv(const std::string& x, casadi_int nrow_x, casadi_int ncol_x,
390  const std::string& y, const std::string& z, bool tr);
391 
395  std::string axpy(casadi_int n, const std::string& a,
396  const std::string& x, const std::string& y);
397 
403  std::string clip_min(const std::string& x, casadi_int n,
404  const std::string& min, const std::string& mask);
405 
411  std::string clip_max(const std::string& x, casadi_int n,
412  const std::string& min, const std::string& mask);
413 
418  std::string vector_fmax(casadi_int n, const std::string& x,
419  const std::string& y, const std::string& z);
420 
425  std::string vector_fmin(casadi_int n, const std::string& x,
426  const std::string& y, const std::string& z);
427 
432  std::string masked_norm_inf(casadi_int n, const std::string& x,
433  const std::string& mask);
434 
435 
439  std::string scal(casadi_int n, const std::string& alpha, const std::string& x);
440 
444  std::string mtimes(const std::string& x, const Sparsity& sp_x,
445  const std::string& y, const Sparsity& sp_y,
446  const std::string& z, const Sparsity& sp_z,
447  const std::string& w, bool tr);
448 
452  std::string mtimes(const std::string& x, casadi_int nrow_x, casadi_int ncol_x,
453  const std::string& y, casadi_int ncol_y,
454  const std::string& z, bool tr);
455 
459  std::string mtimes_dense_sparse(const std::string& x, casadi_int nrow_x,
460  const std::string& y, const Sparsity& sp_y,
461  const std::string& z);
462 
466  std::string trilsolve(const Sparsity& sp_x, const std::string& x, const std::string& y,
467  bool tr, bool unity, casadi_int nrhs);
468 
472  std::string triusolve(const Sparsity& sp_x, const std::string& x, const std::string& y,
473  bool tr, bool unity, casadi_int nrhs);
474 
478  std::string bilin(const std::string& A, const Sparsity& sp_A,
479  const std::string& x, const std::string& y);
480 
484  std::string rank1(const std::string& A, const Sparsity& sp_A, const std::string& alpha,
485  const std::string& x, const std::string& y);
486 
488  std::string logsumexp(const std::string& A, casadi_int n);
489 
493  std::string interpn(const std::string& res, casadi_int ndim, const std::string& grid,
494  const std::string& offset,
495  const std::string& values, const std::string& x,
496  const std::string& lookup_mode, casadi_int m,
497  const std::string& iw, const std::string& w);
498 
502  std::string interpn_grad(const std::string& grad,
503  casadi_int ndim, const std::string& grid,
504  const std::string& offset,
505  const std::string& values, const std::string& x,
506  const std::string& lookup_mode, casadi_int m,
507  const std::string& iw, const std::string& w);
508 
512  std::string trans(const std::string& x, const Sparsity& sp_x,
513  const std::string& y, const Sparsity& sp_y, const std::string& iw);
514 
518  std::string qr(const std::string& sp, const std::string& A,
519  const std::string& w, const std::string& sp_v,
520  const std::string& v, const std::string& sp_r,
521  const std::string& r, const std::string& beta,
522  const std::string& prinv, const std::string& pc);
523 
527  std::string det(const std::string& sp_v, const std::string& v,
528  const std::string& sp_r, const std::string& r, const std::string& beta);
529 
533  std::string qr_solve(const std::string& x, casadi_int nrhs, bool tr,
534  const std::string& sp_v, const std::string& v,
535  const std::string& sp_r, const std::string& r,
536  const std::string& beta, const std::string& prinv,
537  const std::string& pc, const std::string& w);
538 
542  std::string lsqr_solve(const std::string& A, const std::string&x,
543  casadi_int nrhs, bool tr, const std::string& sp, const std::string& w);
544 
548  std::string ldl(const std::string& sp_a, const std::string& a,
549  const std::string& sp_lt, const std::string& lt,
550  const std::string& d, const std::string& p,
551  const std::string& w);
552 
556  std::string ldl_solve(const std::string& x, casadi_int nrhs,
557  const std::string& sp_lt, const std::string& lt,
558  const std::string& d, const std::string& p,
559  const std::string& w);
560 
564  std::string fmax(const std::string& x, const std::string& y);
565 
569  std::string fmin(const std::string& x, const std::string& y);
570 
574  std::string mmax(const std::string& x, casadi_int n, bool is_dense);
575 
579  std::string mmin(const std::string& x, casadi_int n, bool is_dense);
580 
584  std::string vfmax(const std::string& x, casadi_int n, const std::string& y);
585 
589  std::string vfmin(const std::string& x, casadi_int n, const std::string& y);
590 
594  std::string vfmax(const std::string& x, const std::string& n, const std::string& y);
595 
599  std::string vfmin(const std::string& x, const std::string& n, const std::string& y);
600 
604  std::string max(const std::string& x, const std::string& y);
605 
609  std::string min(const std::string& x, const std::string& y);
610 
614  std::string norm_inf(casadi_int n, const std::string& x);
615 
619  std::string norm_1(casadi_int n, const std::string& x);
620 
626  std::string norm_2(casadi_int n, const std::string& x);
627 
631  std::string max_viol(casadi_int n, const std::string& x,
632  const std::string& lb, const std::string& ub);
633 
637  std::string sum_viol(casadi_int n, const std::string& x,
638  const std::string& lb, const std::string& ub);
639 
643  std::string bound_consistency(casadi_int n, const std::string& x,
644  const std::string& lam, const std::string& lbx, const std::string& ubx);
645 
649  std::string lb_eig(const Sparsity& sp_h, const std::string& h);
650 
654  std::string regularize(const Sparsity& sp_h, const std::string& h, const std::string& reg);
655 
659  std::string convexify_eval(const ConvexifyData& d,
660  const std::string& Hin, const std::string& Hout, const std::string& iw, const std::string& w);
661 
665  std::string low(const std::string& x, const std::string& grid,
666  casadi_int ng, casadi_int lookup_mode);
667 
671  std::string declare(std::string s);
672 
676  void comment(const std::string& s);
677 
681  enum Auxiliary {
682  AUX_COPY,
683  AUX_CVX,
684  AUX_CONVEXIFY,
685  AUX_SWAP,
686  AUX_SCAL,
687  AUX_AXPY,
688  AUX_DOT,
689  AUX_BILIN,
690  AUX_KRON,
691  AUX_KRON_DENSE,
692  AUX_KRON_DENSE_SPARSE,
693  AUX_KRON_SPARSE_DENSE,
694  AUX_KRON_CONTRACT_INNER,
695  AUX_KRON_CONTRACT_INNER_DENSE,
696  AUX_KRON_CONTRACT_INNER_DENSE_SPARSE,
697  AUX_KRON_CONTRACT_INNER_SPARSE_DENSE,
698  AUX_KRON_CONTRACT_OUTER,
699  AUX_KRON_CONTRACT_OUTER_DENSE,
700  AUX_KRON_CONTRACT_OUTER_DENSE_SPARSE,
701  AUX_KRON_CONTRACT_OUTER_SPARSE_DENSE,
702  AUX_RANK1,
703  AUX_NORM_1,
704  AUX_NORM_2,
705  AUX_CLIP_MAX,
706  AUX_CLIP_MIN,
707  AUX_VECTOR_FMAX,
708  AUX_VECTOR_FMIN,
709  AUX_NORM_INF,
710  AUX_MASKED_NORM_INF,
711  AUX_IAMAX,
712  AUX_CLEAR,
713  AUX_FILL,
714  AUX_MV,
715  AUX_MV_DENSE,
716  AUX_MTIMES,
717  AUX_MTIMES_DENSE,
718  AUX_MTIMES_DENSE_SPARSE,
719  AUX_TRILSOLVE,
720  AUX_TRIUSOLVE,
721  AUX_PROJECT,
722  AUX_TRI_PROJECT,
723  AUX_DENSIFY,
724  AUX_SPARSIFY,
725  AUX_TRANS,
726  AUX_TO_MEX,
727  AUX_FROM_MEX,
728  AUX_INTERPN,
729  AUX_INTERPN_GRAD,
730  AUX_FLIP,
731  AUX_INTERPN_WEIGHTS,
732  AUX_LOW,
733  AUX_INTERPN_INTERPOLATE,
734  AUX_DE_BOOR,
735  AUX_TENSOR_TTV,
736  AUX_ND_BOOR_EVAL,
737  AUX_FINITE_DIFF,
738  AUX_QR,
739  AUX_DET,
740  AUX_QP,
741  AUX_QRQP,
742  AUX_SOCP,
743  AUX_NLP,
744  AUX_SQPMETHOD,
745  AUX_FEASIBLESQPMETHOD,
746  AUX_LDL,
747  AUX_NEWTON,
748  AUX_IVP,
749  AUX_IVP_ADAPT,
750  AUX_IVP_EVENT,
751  AUX_ROSENBROCK,
752  AUX_ERK,
753  AUX_TO_DOUBLE,
754  AUX_TO_INT,
755  AUX_CAST,
756  AUX_SQ,
757  AUX_SIGN,
758  AUX_IF_ELSE,
759  AUX_PRINTF,
760  AUX_FMIN,
761  AUX_FMAX,
762  AUX_FABS,
763  AUX_MIN,
764  AUX_MAX,
765  AUX_VFMIN,
766  AUX_VFMAX,
767  AUX_MAX_VIOL,
768  AUX_SUM_VIOL,
769  AUX_SUM,
770  AUX_REGULARIZE,
771  AUX_INF,
772  AUX_NAN,
773  AUX_REAL_MIN,
774  AUX_ISINF,
775  AUX_ISFINITE,
776  AUX_BOUNDS_CONSISTENCY,
777  AUX_LSQR,
778  AUX_FILE_SLURP,
779  AUX_CACHE,
780  AUX_LOG1P,
781  AUX_EXPM1,
782  AUX_HYPOT,
783  AUX_MMIN,
784  AUX_MMAX,
785  AUX_LOGSUMEXP,
786  AUX_SPARSITY,
787  AUX_BFGS,
788  AUX_ORACLE_CALLBACK,
789  AUX_OCP_BLOCK,
790  AUX_ORACLE,
791  AUX_SCALED_COPY,
792  AUX_BLAZING_COMMON,
793  AUX_BLAZING_1D_BOOR_EVAL,
794  AUX_BLAZING_2D_BOOR_EVAL,
795  AUX_BLAZING_3D_BOOR_EVAL,
796  AUX_BLAZING_4D_BOOR_EVAL,
797  AUX_BLAZING_5D_BOOR_EVAL,
798  AUX_PRINTME,
799  AUX_PRINT_SCALAR,
800  AUX_PRINT_VECTOR,
801  AUX_PRINT_CANONICAL,
802  AUX_FPRINTF_SCALAR,
803  AUX_FPRINTF_VECTOR,
804  AUX_TO_FILE,
805  AUX_THREADS
806  };
807 
811  void add_auxiliary(Auxiliary f, const std::vector<std::string>& inst = {"casadi_real"});
812 
816  void add_io_sparsities(const std::string& name,
817  const std::vector<Sparsity>& sp_in,
818  const std::vector<Sparsity>& sp_out);
819 
821  std::string work(casadi_int n, casadi_int sz, bool is_ref) const;
822 
824  std::string workel(casadi_int n) const;
825 
829  void reserve_work(casadi_int n);
830 
837  void set_codegen_sz_w(const FunctionInternal* f, size_t sz_w);
838 
844  bool get_codegen_sz_w(const FunctionInternal* f, size_t& sz_w) const;
845 
847  static std::string array(const std::string& type, const std::string& name, casadi_int len,
848  const std::string& def=std::string());
849 
853  void print_vector(std::ostream &s, const std::string& name,
854  const std::vector<casadi_int>& v);
855 
859  void print_vector(std::ostream &s, const std::string& name,
860  const std::vector<char>& v);
861 
865  void print_vector(std::ostream &s, const std::string& name,
866  const std::vector<double>& v);
867 
871  void print_vector(std::ostream &s, const std::string& name,
872  const std::vector<std::string>& v);
873 
877  std::string print_canonical(const Sparsity& sp, const std::string& arg);
878 
882  std::string print_vector(casadi_int sz, const std::string& arg);
883 
887  std::string print_scalar(const std::string& arg);
888 
892  std::string fprintf_scalar(const std::string& f, const std::string& arg);
893 
897  std::string fprintf_vector(const std::string& f, casadi_int sz,
898  const std::string& arg, const std::string& sep);
899 
903  std::string copy(const std::string& arg, std::size_t n, const std::string& res);
904  void copy_check(const std::string& arg, std::size_t n, const std::string& res,
905  bool check_lhs=true, bool check_rhs=true);
906  void copy_default(const std::string& arg, std::size_t n, const std::string& res,
907  const std::string& def, bool check_rhs=true);
908 
909  // Should we elide a copy?
910  bool elide_copy(casadi_int sz);
911 
915  std::string fill(const std::string& res, std::size_t n, const std::string& v);
916 
920  std::string clear(const std::string& res, std::size_t n);
921 
925  std::string arg(casadi_int i) const;
926 
930  std::string res(casadi_int i) const;
931 
935  std::string mem(const Function& f);
936 
940  std::string project(const std::string& arg, const Sparsity& sp_arg,
941  const std::string& res, const Sparsity& sp_res,
942  const std::string& w);
943 
947  std::string tri_project(const std::string& arg, const Sparsity& sp_arg,
948  const std::string& res, bool lower);
949 
953  std::string densify(const std::string& arg, const Sparsity& sp_arg,
954  const std::string& res, bool tr=false);
955 
959  std::string sparsify(const std::string& arg, const std::string& res,
960  const Sparsity& sp_res, bool tr=false);
961 
965  std::string to_mex(const Sparsity& sp, const std::string& arg);
966 
970  std::string from_mex(std::string& arg,
971  const std::string& res, std::size_t res_off, const Sparsity& sp_res,
972  const std::string& w);
973 
977  static std::string fmu_helpers(const std::string& modelname);
978 
982  std::string printf(const std::string& str,
983  const std::vector<std::string>& arg=std::vector<std::string>());
984  std::string printf(const std::string& str, const std::string& arg1);
985  std::string printf(const std::string& str, const std::string& arg1, const std::string& arg2);
986  std::string printf(const std::string& str, const std::string& arg1, const std::string& arg2,
987  const std::string& arg3);
988 
992  std::string print_op(casadi_int op, const std::string& a0);
993  std::string print_op(casadi_int op, const std::string& a0, const std::string& a1);
994 
998  std::string file_slurp(const std::string& fname, casadi_int n, const std::string& a);
999 
1003  std::string to_file(const std::string& f, const Sparsity& sp, const std::string& x);
1004 
1008  void generate_dump(const Function& f, const std::string& arr, bool is_input);
1009 
1013  void generate_print(const Function& f, const std::string& arr, bool is_input);
1014 
1018  std::string cache_check(const std::string& key, const std::string& cache,
1019  const std::string& loc, casadi_int stride, casadi_int sz, casadi_int key_sz,
1020  const std::string& val);
1021 
1023  static std::string casadi_version();
1024 
1026  static void stream_open(std::ostream& f, bool cpp);
1027 
1029  static void stream_close(std::ostream& f, bool cpp);
1030 
1034  void sz_work(size_t& sz_arg, size_t& sz_res, size_t& sz_iw, size_t& sz_w) const;
1035 
1036  private:
1037 
1038  // Generate casadi_real definition
1039  void generate_casadi_real(std::ostream &s) const;
1040 
1041  // Generate casadi_int definition
1042  void generate_casadi_int(std::ostream &s) const;
1043 
1044  // Generate mex entry point
1045  void generate_mex(std::ostream &s) const;
1046 
1047  // Generate function specific code for Simulink s-Function
1048  std::string codegen_sfunction(const Function& f) const;
1049 
1050  // Export s-Function to file
1051  void generate_sfunction(const std::string& name, const std::string& sfunction) const;
1052 
1053  // Generate main entry point
1054  void generate_main(std::ostream &s) const;
1055 
1056  // Generate export symbol macros
1057  void generate_export_symbol(std::ostream &s) const;
1058 
1059  // Generate import symbol macros
1060  void generate_import_symbol(std::ostream &s) const;
1061 
1062  // private:
1063  public:
1065 
1066  // Name of generated file
1067  std::string name, suffix;
1068 
1069  // Real-type used for the codegen
1070  std::string casadi_real_type;
1071 
1072  // Int-type used for the codegen
1073  std::string casadi_int_type;
1074 
1075  // Should we create a memory entry point?
1076  bool with_mem;
1077 
1078  // Generate header file?
1079  bool with_header;
1080 
1081  // Are we creating a MEX file?
1082  bool mex;
1083 
1084  // Are we creating a s-function?
1085  bool with_sfunction;
1086  std::vector<std::string> added_sfunctions;
1087 
1088  // Unroll arguments?
1089  bool unroll_args;
1090 
1091  // Emit runtime auxiliary functions with 'static' storage class?
1092  bool static_aux;
1093 
1094  // Emit runtime auxiliary functions with 'inline' hint?
1095  bool inline_aux;
1096 
1097  // Verbose codegen?
1098  bool verbose;
1099 
1100  // Verbose runtime?
1101  bool verbose_runtime;
1102 
1103  // Are we generating C++?
1104  bool cpp;
1105 
1106  // Should we generate a main (allowing evaluation from command line)
1107  bool main;
1108 
1109  // Should we include mayth library?
1110  bool include_math;
1111 
1112  // Do we want to be lean on stack usage?
1113  bool avoid_stack_;
1114 
1115  std::string infinity, nan, real_min;
1116 
1123  bool codegen_scalars;
1124 
1125  // Have a flag for exporting/importing symbols
1126  bool with_export, with_import;
1127 
1128  // Maximum number of declarations per line
1129  casadi_int max_declarations_per_line;
1130 
1131  // Maximum number of initializer elements per line
1132  casadi_int max_initializer_elements_per_line;
1133 
1134  // Force the external API to use canonical sparsity
1135  bool force_canonical;
1136 
1137  // Route L1 ops (axpy/dot/scal/norm_1/norm_2) through the active BLAS
1138  // plugin in generated code; off => built-in reference kernels.
1139  bool l1_blas;
1140 
1141  // Emit thread-safe checkout/release?
1142  bool thread_safe_;
1143 
1144  // Prefix symbols in DLLs?
1145  std::string dll_export, dll_import;
1146 
1147  // Prefix
1148  std::string prefix;
1149 
1150  // Prefix/suffix for dump directory in codegen
1151  std::string dump_dir_prefix;
1152  std::string dump_dir_suffix;
1153 
1154  // std::stringstreams holding the different parts of the file being generated
1155  std::stringstream includes;
1156  std::stringstream auxiliaries;
1157  std::stringstream body;
1158  std::stringstream header;
1159  std::stringstream buffer;
1160 
1161  // Are we at a new line?
1162  bool newline_;
1163 
1164  // Indentation
1165  casadi_int indent_;
1166  casadi_int current_indent_;
1167 
1168  // Number of zeros/ones
1169  casadi_int sz_zeros_;
1170  casadi_int sz_ones_;
1171 
1172  casadi_int padding_length_;
1173 
1174  // Names of exposed functions
1175  std::vector<std::string> exposed_fname;
1176 
1177  // Code generated sparsities
1178  std::set<std::string> sparsity_meta;
1179 
1180  // Set of already included header files
1181  std::set<std::string> added_includes_;
1182  std::set<std::string> added_externals_;
1183  std::set<std::string> external_names_;
1184  std::set<std::string> added_shorthands_;
1185  std::set<std::string> added_runtimes_;
1186  std::multimap<Auxiliary, std::vector<std::string>> added_auxiliaries_;
1187  std::multimap<size_t, size_t> added_double_constants_;
1188  std::multimap<size_t, size_t> added_integer_constants_;
1189  std::multimap<size_t, size_t> added_char_constants_;
1190  std::multimap<size_t, size_t> added_string_constants_;
1191  std::map<std::string, std::pair<std::string, std::string> > local_variables_;
1192  std::vector<std::string> local_cleanup_;
1193  bool local_void_;
1194  std::map<std::string, std::string> local_default_;
1195  std::map<const void *, casadi_int> file_scope_double_;
1196  std::map<const void *, casadi_int> file_scope_integer_;
1197  std::vector< std::vector<double> > pool_double_defaults_;
1198  std::map<std::string, casadi_int> pool_double_;
1199  std::map<const FunctionInternal*, std::set<std::string> > local_mutexes_;
1200 
1201  // Work vector sizes of generated function bodies, cf. set_codegen_sz_w
1202  std::map<const FunctionInternal*, size_t> codegen_sz_w_;
1203 
1204  // Added functions
1205  struct FunctionMeta {
1206  // The function object
1207  Function f;
1208  // Name in codegen
1209  std::string codegen_name;
1210  };
1211  std::vector<FunctionMeta> added_functions_;
1212 
1213  // Counters for creating unique identifiers
1214  std::map<std::string, std::map<FunctionInternal*, casadi_int> > added_wrappers_;
1215 
1216  // Constants
1217  std::vector<std::vector<double> > double_constants_;
1218  std::vector<std::vector<casadi_int> > integer_constants_;
1219  std::vector<std::vector<char> > char_constants_;
1220  std::vector<std::vector<std::string> > string_constants_;
1221 
1222  // Does any function need thread-local memory?
1223  bool needs_mem_;
1224 
1225  // Hash a vector
1226  static size_t hash(const std::vector<double>& v);
1227  static size_t hash(const std::vector<casadi_int>& v);
1228  static size_t hash(const std::vector<char>& v);
1229  static size_t hash(const std::vector<std::string>& v);
1230 
1231  std::string wrapper(const Function& base, const std::string& name);
1232 
1233  // Compare two vectors
1234  template<typename T>
1235  static bool equal(const std::vector<T>& v1, const std::vector<T>& v2) {
1236  if (v1.size()!=v2.size()) return false;
1237  for (casadi_int j=0; j<v1.size(); ++j) {
1238  if (v1[j]!=v2[j]) return false;
1239  }
1240  return true;
1241  }
1243 #endif // SWIG
1244  };
1245 
1246 
1247 } // namespace casadi
1248 
1249 #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:126
General sparsity class.
Definition: sparsity.hpp:200
The casadi namespace.
Definition: archiver.hpp:32
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.