external.cpp
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 #include "external_impl.hpp"
27 #include "casadi_misc.hpp"
28 #include "serializing_stream.hpp"
29 #include <casadi/config.h>
30 
31 #include <fstream>
32 #include <iostream>
33 #include <sstream>
34 
35 // Set default shared library suffix
36 #ifndef SHARED_LIBRARY_SUFFIX
37 #define SHARED_LIBRARY_SUFFIX CASADI_SHARED_LIBRARY_SUFFIX
38 #endif // SHARED_LIBRARY_SUFFIX
39 
40 namespace casadi {
41 
42 Function external(const std::string& name, const Importer& li,
43  const Dict& opts) {
44  std::vector<std::string> config_args;
45  Dict opts_filtered = extract_from_dict(opts, "config_args", config_args);
46  config_args.insert(config_args.begin(), li.library());
47  return Function::create(new GenericExternal(name, li, config_args), opts_filtered);
48 }
49 
50 Function external(const std::string& name, const Dict& opts) {
51  return external(name, "./" + name + SHARED_LIBRARY_SUFFIX, opts);
52 }
53 
54 Function external(const std::string& name, const std::string& bin_name,
55  const Dict& opts) {
56  return external(name, Importer(bin_name, "dll"), opts);
57 }
58 
59 External::External(const std::string& name, const Importer& li,
60  const std::vector<std::string> config_args)
61  : FunctionInternal(name), li_(li), config_args_(config_args) {
62 
64 }
65 
67  return config_ || incref_ || decref_ || get_default_in_ ||
70 }
71 
73  // Increasing/decreasing reference counter
74  config_ = (config_t)li_.get_function(name_ + "_config");
75 
76  incref_ = (signal_t)li_.get_function(name_ + "_incref");
77  decref_ = (signal_t)li_.get_function(name_ + "_decref");
78 
79  casadi_assert(static_cast<bool>(incref_) == static_cast<bool>(decref_),
80  "External must either define both incref and decref or neither.");
81 
82  // Getting default arguments
83  get_default_in_ = (default_t)li_.get_function(name_ + "_default_in");
84 
85  // Getting number of inputs and outputs
86  get_n_in_ = (getint_t)li_.get_function(name_ + "_n_in");
87  get_n_out_ = (getint_t)li_.get_function(name_ + "_n_out");
88 
89  // Getting names of inputs and outputs
90  get_name_in_ = (name_t)li_.get_function(name_ + "_name_in");
91  get_name_out_ = (name_t)li_.get_function(name_ + "_name_out");
92 
93  // Work vector sizes
94  work_ = (work_t)li_.get_function(name_ + "_work");
95 
96  if (config_) {
97  args_.resize(config_args_.size());
98  for (int i=0;i<config_args_.size();++i) {
99  args_[i] = config_args_.at(i).c_str();
100  }
101  int flag = config_(args_.size(), get_ptr(args_));
102  casadi_assert(flag==0, "config failed.");
103  }
104 
105  // Increase reference counter - external function memory initialized at this point
106  if (incref_) incref_();
107 }
108 
109 GenericExternal::GenericExternal(const std::string& name, const Importer& li,
110  const std::vector<std::string> arguments)
111  : External(name, li, arguments) {
112 
114 }
115 
117  return External::any_symbol_found() ||
118  get_sparsity_in_ || get_sparsity_out_ ||
119  get_diff_in_ || get_diff_out_ ||
120  checkout_ || release_ ||
121  eval_;
122 }
123 
125 
126  // Functions for retrieving sparsities of inputs and outputs
127  get_sparsity_in_ = (sparsity_t)li_.get_function(name_ + "_sparsity_in");
128  get_sparsity_out_ = (sparsity_t)li_.get_function(name_ + "_sparsity_out");
129 
130  // Differentiability of inputs and outputs
131  get_diff_in_ = (diff_t)li_.get_function(name_ + "_diff_in");
132  get_diff_out_ = (diff_t)li_.get_function(name_ + "_diff_out");
133 
134  // Memory management functions
135  checkout_ = (casadi_checkout_t) li_.get_function(name_ + "_checkout");
136  release_ = (casadi_release_t) li_.get_function(name_ + "_release");
137 
138  casadi_assert(static_cast<bool>(checkout_) == static_cast<bool>(release_),
139  "External must either define both checkout and release or neither.");
140 
141  // Function for numerical evaluation
143 
144  // Sparsity patterns of Jacobians
145  get_jac_sparsity_ = (sparsity_t)li_.get_function("jac_" + name_ + "_sparsity_out");
146 }
147 
149  if (decref_) decref_();
150  clear_mem();
151 }
152 
154  if (get_n_in_) {
155  return get_n_in_();
156  } else if (li_.has_meta(name_ + "_N_IN")) {
157  return li_.meta_int(name_ + "_N_IN");
158  } else {
159  // Fall back to base class
161  }
162 }
163 
165  if (get_n_out_) {
166  return get_n_out_();
167  } else if (li_.has_meta(name_ + "_N_OUT")) {
168  return li_.meta_int(name_ + "_N_OUT");
169  } else {
170  // Fall back to base class
172  }
173 }
174 
175 double External::get_default_in(casadi_int i) const {
176  if (get_default_in_) {
177  return get_default_in_(i);
178  } else {
179  // Fall back to base class
181  }
182 }
183 
184 std::string External::get_name_in(casadi_int i) {
185  if (get_name_in_) {
186  // Use function pointer
187  const char* n = get_name_in_(i);
188  casadi_assert(n!=nullptr, "Error querying input name");
189  return n;
190  } else if (li_.has_meta(name_ + "_NAME_IN", i)) {
191  // Read meta
192  return li_.meta_string(name_ + "_NAME_IN", i);
193  } else {
194  // Default name
196  }
197 }
198 
199 std::string External::get_name_out(casadi_int i) {
200  if (get_name_out_) {
201  // Use function pointer
202  const char* n = get_name_out_(i);
203  casadi_assert(n!=nullptr, "Error querying output name");
204  return n;
205  } else if (li_.has_meta(name_ + "_NAME_OUT", i)) {
206  // Read meta
207  return li_.meta_string(name_ + "_NAME_OUT", i);
208  } else {
209  // Default name
211  }
212 }
213 
215  // Use sparsity retrieval function, if present
216  if (get_sparsity_in_) {
217  return Sparsity::compressed(get_sparsity_in_(i));
218  } else if (li_.has_meta(name_ + "_SPARSITY_IN", i)) {
219  return Sparsity::compressed(li_.meta_vector<casadi_int>(name_ + "_SPARSITY_IN", i));
220  } else {
221  // Fall back to base class
223  }
224 }
225 
227  // Use sparsity retrieval function, if present
228  if (get_sparsity_out_) {
229  return Sparsity::compressed(get_sparsity_out_(i));
230  } else if (li_.has_meta(name_ + "_SPARSITY_OUT", i)) {
231  return Sparsity::compressed(li_.meta_vector<casadi_int>(name_ + "_SPARSITY_OUT", i));
232  } else {
233  // Fall back to base class
235  }
236 }
237 
238 bool GenericExternal::has_jac_sparsity(casadi_int oind, casadi_int iind) const {
239  // Flat index
240  casadi_int ind = iind + oind * n_in_;
241  // Jacobian sparsity pattern known?
242  if (get_jac_sparsity_ || li_.has_meta("JAC_" + name_ + "_SPARSITY_OUT", ind)) {
243  return true;
244  } else {
245  // Fall back to base class
246  return FunctionInternal::has_jac_sparsity(oind, iind);
247  }
248 }
249 
250 Sparsity GenericExternal::get_jac_sparsity(casadi_int oind, casadi_int iind,
251  bool symmetric) const {
252  // Flat index
253  casadi_int ind = iind + oind * n_in_;
254  // Use sparsity retrieval function, if present
255  if (get_jac_sparsity_) {
256  return Sparsity::compressed(get_jac_sparsity_(ind));
257  } else if (li_.has_meta("JAC_" + name_ + "_SPARSITY_OUT", ind)) {
258  return Sparsity::compressed(
259  li_.meta_vector<casadi_int>("jac_" + name_ + "_SPARSITY_OUT", ind));
260  } else {
261  // Fall back to base class
262  return FunctionInternal::get_jac_sparsity(oind, iind, symmetric);
263  }
264 }
265 
266 bool GenericExternal::get_diff_in(casadi_int i) {
267  if (get_diff_in_) {
268  // Query function exists
269  return get_diff_in_(i);
270  } else {
271  // Fall back to base class
273  }
274 }
275 
276 bool GenericExternal::get_diff_out(casadi_int i) {
277  if (get_diff_out_) {
278  // Query function exists
279  return get_diff_out_(i);
280  } else {
281  // Fall back to base class
283  }
284 }
285 
286 void External::init(const Dict& opts) {
287  // Call the initialization method of the base class
289 
290  casadi_assert(any_symbol_found(),
291  "Could not find any function/symbol starting with '" + name_ + "_'. "
292  "Make sure to read documentation of `external()` for proper usage.");
293 
294  // Reference counting?
295  has_refcount_ = li_.has_function(name_ + "_incref");
296  casadi_assert(has_refcount_==li_.has_function(name_ + "_decref"),
297  "External functions must provide functions for both increasing "
298  "and decreasing the reference count, or neither.");
299 
300  if (li_.has_function(name_ + "_config")) {
301  casadi_assert(has_refcount_,
302  "External functions that feature a config functions must also implement incref.");
303  }
304 
305  // Allocate work vectors
306  casadi_int sz_arg=0, sz_res=0, sz_iw=0, sz_w=0;
307  if (work_) {
308  casadi_int flag = work_(&sz_arg, &sz_res, &sz_iw, &sz_w);
309  casadi_assert(flag==0, "External: \"work\" failed");
310  } else if (li_.has_meta(name_ + "_WORK")) {
311  std::vector<casadi_int> v = li_.meta_vector<casadi_int>(name_ + "_WORK");
312  casadi_assert_dev(v.size()==4);
313  sz_arg = v[0];
314  sz_res = v[1];
315  sz_iw = v[2];
316  sz_w = v[3];
317  }
318 
319  // Work vectors
320  alloc_arg(sz_arg);
321  alloc_res(sz_res);
322  alloc_iw(sz_iw);
323  alloc_w(sz_w);
324 }
325 
326 void GenericExternal::init(const Dict& opts) {
327  // Call recursively
328  External::init(opts);
329 }
330 
332  if (!li_.inlined(name_)) {
333  g.add_external(signature(name_) + ";");
334  if (checkout_) g.add_external("int " + name_ + "_checkout(void);");
335  if (release_) g.add_external("void " + name_ + "_release(int mem);");
336  if (incref_) g.add_external("void " + name_ + "_incref(void);");
337  if (decref_) g.add_external("void " + name_ + "_decref(void);");
338  if (config_) g.add_external("int " + name_ + "_config(int argc, const char**);");
339  }
340 }
341 
343  if (li_.inlined(name_)) {
344  // Function body is inlined
345  g << li_.body(name_) << "\n";
346  } else {
347  g << "if (" << name_ << "(arg, res, iw, w, mem)) return 1;\n";
348  }
349 }
350 
351 std::string External::codegen_mem_type() const {
352  if (checkout_) return "nonempty";
353  return "";
354 }
355 
357  if (checkout_) {
358  g << "return " << name_ << "_checkout();\n";
359  } else {
360  g << "return 0;\n";
361  }
362 }
363 
365  if (release_) {
366  g << name_ << "_release(mem);\n";
367  }
368 }
369 
371  if (incref_) {
372  if (config_) {
373  g << name_ << "_config(" << config_args_.size() << ", "
374  << g.constant(config_args_) << ");\n";
375  }
376  g << name_ << "_incref();\n";
377  }
378 }
379 
381  if (decref_) {
382  g << name_ << "_decref();\n";
383  }
384 }
385 
387  g << "return 0;\n";
388 }
389 
391  g << "return 0;\n";
392 }
393 
395 }
396 
398  if (FunctionInternal::has_jacobian()) return true;
399  return li_.has_function("jac_" + name_);
400 }
401 
403 ::get_jacobian(const std::string& name,
404  const std::vector<std::string>& inames,
405  const std::vector<std::string>& onames,
406  const Dict& opts) const {
407  if (has_jacobian()) {
408  return external(name, li_, opts);
409  } else {
410  return FunctionInternal::get_jacobian(name, inames, onames, opts);
411  }
412 }
413 
415 ::get_forward(casadi_int nfwd, const std::string& name,
416  const std::vector<std::string>& inames,
417  const std::vector<std::string>& onames,
418  const Dict& opts) const {
419  // Consistency check
420  casadi_int n=1;
421  while (n<nfwd) n*=2;
422  if (n!=nfwd || !has_forward(nfwd)) {
423  // Inefficient code to be replaced later
424  Function fwd1 = forward(1);
425  return fwd1.map(name, "serial", nfwd, range(n_in_+n_out_), std::vector<casadi_int>(), opts);
426  //casadi_error("Internal error: Refactoring needed, cf. #1055");
427  }
428  return external(name, li_, opts);
429 }
430 
431 bool External::has_forward(casadi_int nfwd) const {
432  return li_.has_function("fwd" + str(nfwd) + "_" + name_);
433 }
434 
436 ::get_reverse(casadi_int nadj, const std::string& name,
437  const std::vector<std::string>& inames,
438  const std::vector<std::string>& onames,
439  const Dict& opts) const {
440  // Consistency check
441  casadi_int n=1;
442  while (n<nadj) n*=2;
443  if (n!=nadj || !has_reverse(nadj)) {
444  // Inefficient code to be replaced later
445  Function adj1 = reverse(1);
446  return adj1.map(name, "serial", nadj, range(n_in_+n_out_), std::vector<casadi_int>(), opts);
447  //casadi_error("Internal error: Refactoring needed, cf. #1055");
448  }
449  return external(name, li_, opts);
450 }
451 
452 bool External::has_reverse(casadi_int nadj) const {
453  return li_.has_function("adj" + str(nadj) + "_" + name_);
454 }
455 
456 Function External::factory(const std::string& name,
457  const std::vector<std::string>& s_in,
458  const std::vector<std::string>& s_out,
459  const Function::AuxOut& aux,
460  const Dict& opts) const {
461  // If not available, call base class function
462  if (!li_.has_function(name)) {
463  return FunctionInternal::factory(name, s_in, s_out, aux, opts);
464  }
465 
466  // Retrieve function
467  Function ret = external(name, li_, opts);
468 
469  // Replace colons in input names
470  std::vector<std::string> s_io(s_in);
471  for (std::string& s : s_io) replace(s.begin(), s.end(), ':', '_');
472 
473  // Inputs consistency checks
474  casadi_assert(s_in.size() == ret.n_in(),
475  "Inconsistent number of inputs. Expected " + str(s_in.size())+ " "
476  "(" + str(s_io) + "), got " + str(ret.n_in()) + ".");
477  for (size_t i = 0; i < s_in.size(); ++i) {
478  casadi_assert(s_io[i] == ret.name_in(i),
479  "Inconsistent input name. Expected: " + str(s_io) + ", "
480  "got " + ret.name_in(i) + " for input " + str(i));
481  }
482 
483  // Replace colons in output names
484  s_io = s_out;
485  for (std::string& s : s_io) replace(s.begin(), s.end(), ':', '_');
486 
487  // Outputs consistency checks
488  casadi_assert(s_out.size() == ret.n_out(),
489  "Inconsistent number of outputs. Expected " + str(s_out.size()) + " "
490  "(" + str(s_io) + "), got " + str(ret.n_out()) + ".");
491  for (size_t i = 0; i < s_out.size(); ++i) {
492  casadi_assert(s_io[i] == ret.name_out(i),
493  "Inconsistent output name. Expected: " + str(s_io) + ", "
494  "got " + ret.name_out(i) + " for output " + str(i));
495  }
496 
497  return ret;
498 }
499 
502 
503  s.version("External", 2);
504  s.pack("External::int_data", int_data_);
505  s.pack("External::real_data", real_data_);
506  s.pack("External::string_data", string_data_);
507  s.pack("External::li", li_);
508  std::vector<std::string> config_args = vector_tail(config_args_);
509  s.pack("External::config_args", config_args);
510 }
511 
513  s.version("GenericExternal", 1);
514  char type;
515  s.unpack("GenericExternal::type", type);
516  switch (type) {
517  case 'g': return new GenericExternal(s);
518  default:
519  casadi_error("External::deserialize error");
520  }
521 }
522 
525  s.version("GenericExternal", 1);
526  s.pack("GenericExternal::type", 'g');
527 }
528 
530  int version = s.version("External", 1, 2);
531  s.unpack("External::int_data", int_data_);
532  s.unpack("External::real_data", real_data_);
533  s.unpack("External::string_data", string_data_);
534  s.unpack("External::li", li_);
535  if (version>=2) {
536  s.unpack("External::config_args", config_args_);
537  config_args_.insert(config_args_.begin(), li_.library());
538  }
539 
541 }
542 
545 }
546 
547 } // namespace casadi
Helper class for C code generation.
std::string constant(const std::vector< casadi_int > &v)
Represent an array constant; adding it when new.
void add_external(const std::string &new_external)
Add an external function declaration.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
void version(const std::string &name, int v)
void codegen_body(CodeGenerator &g) const override
Generate code for the body of the C function.
Definition: external.cpp:342
size_t get_n_out() override
Number of function inputs and outputs.
Definition: external.cpp:164
std::vector< double > real_data_
Data vectors.
void codegen_init_mem(CodeGenerator &g) const override
Codegen decref for init_mem.
Definition: external.cpp:386
External(const std::string &name, const Importer &li, const std::vector< std::string > config_args=std::vector< std::string >())
Constructor.
Definition: external.cpp:59
std::vector< const char * > args_
Importer li_
Information about the library.
virtual void init_external()
Initialize members that are unique.
Definition: external.cpp:72
bool has_reverse(casadi_int nadj) const override
Reverse mode derivatives.
Definition: external.cpp:452
std::string codegen_mem_type() const override
Thread-local memory object type.
Definition: external.cpp:351
default_t get_default_in_
Get default inputs.
std::string string_data_
Data vectors.
std::vector< std::string > config_args_
Arguments as passed to init.
size_t get_n_in() override
Number of function inputs and outputs.
Definition: external.cpp:153
void codegen_incref(CodeGenerator &g) const override
Codegen incref for dependencies.
Definition: external.cpp:370
void codegen_declarations(CodeGenerator &g) const override
Generate code for the declarations of the C function.
Definition: external.cpp:331
Function factory(const std::string &name, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux, const Dict &opts) const override
Definition: external.cpp:456
bool has_jacobian() const override
Full Jacobian.
Definition: external.cpp:397
bool has_forward(casadi_int nfwd) const override
Forward mode derivatives.
Definition: external.cpp:431
signal_t incref_
Increase/decrease reference counter.
void codegen_alloc_mem(CodeGenerator &g) const override
Codegen decref for alloc_mem.
Definition: external.cpp:390
void codegen_release(CodeGenerator &g) const override
Codegen for release.
Definition: external.cpp:364
Function get_reverse(casadi_int nadj, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Reverse mode derivatives.
Definition: external.cpp:436
void codegen_free_mem(CodeGenerator &g) const override
Codegen for free_mem.
Definition: external.cpp:394
std::vector< casadi_int > int_data_
Data vectors.
work_t work_
Work vector sizes.
getint_t get_n_in_
Number of inputs and outputs.
std::string get_name_in(casadi_int i) override
Names of function input and outputs.
Definition: external.cpp:184
Function get_forward(casadi_int nfwd, const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Forward mode derivatives.
Definition: external.cpp:415
Function get_jacobian(const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const override
Full Jacobian.
Definition: external.cpp:403
~External() override=0
Destructor.
Definition: external.cpp:148
virtual bool any_symbol_found() const
Any symbol found?
Definition: external.cpp:66
void codegen_decref(CodeGenerator &g) const override
Codegen decref for dependencies.
Definition: external.cpp:380
double get_default_in(casadi_int i) const override
Default inputs.
Definition: external.cpp:175
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize into MX.
Definition: external.cpp:512
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
Definition: external.cpp:500
config_t config_
Initialize.
name_t get_name_in_
Names of inputs and outputs.
void init(const Dict &opts) override
Initialize.
Definition: external.cpp:286
void codegen_checkout(CodeGenerator &g) const override
Codegen for checkout.
Definition: external.cpp:356
std::string get_name_out(casadi_int i) override
Names of function input and outputs.
Definition: external.cpp:199
Internal class for Function.
bool has_refcount_
Reference counting in codegen?
void alloc_iw(size_t sz_iw, bool persistent=false)
Ensure required length of iw field.
void init(const Dict &opts) override
Initialize.
void serialize_body(SerializingStream &s) const override
Serialize an object without type information.
void alloc_res(size_t sz_res, bool persistent=false)
Ensure required length of res field.
virtual Function factory(const std::string &name, const std::vector< std::string > &s_in, const std::vector< std::string > &s_out, const Function::AuxOut &aux, const Dict &opts) const
casadi_release_t release_
Release redirected to a C function.
virtual bool has_jac_sparsity(casadi_int oind, casadi_int iind) const
Get Jacobian sparsity.
void alloc_arg(size_t sz_arg, bool persistent=false)
Ensure required length of arg field.
virtual bool has_jacobian() const
Return Jacobian of all input elements with respect to all output elements.
eval_t eval_
Numerical evaluation redirected to a C function.
size_t n_in_
Number of inputs and outputs.
size_t sz_res() const
Get required length of res field.
virtual size_t get_n_out()
Are all inputs and outputs scalar.
casadi_checkout_t checkout_
Checkout redirected to a C function.
virtual bool get_diff_in(casadi_int i)
Which inputs are differentiable.
void serialize_type(SerializingStream &s) const override
Serialize type information.
virtual std::string get_name_out(casadi_int i)
Names of function input and outputs.
virtual Sparsity get_sparsity_out(casadi_int i)
Get sparsity of a given output.
size_t sz_w() const
Get required length of w field.
virtual Sparsity get_jac_sparsity(casadi_int oind, casadi_int iind, bool symmetric) const
Get Jacobian sparsity.
void alloc_w(size_t sz_w, bool persistent=false)
Ensure required length of w field.
std::string signature(const std::string &fname) const
Code generate the function.
virtual Function get_jacobian(const std::string &name, const std::vector< std::string > &inames, const std::vector< std::string > &onames, const Dict &opts) const
Return Jacobian of all input elements with respect to all output elements.
size_t sz_arg() const
Get required length of arg field.
size_t sz_iw() const
Get required length of iw field.
virtual bool get_diff_out(casadi_int i)
Which outputs are differentiable.
virtual std::string get_name_in(casadi_int i)
Names of function input and outputs.
virtual size_t get_n_in()
Number of function inputs and outputs.
virtual double get_default_in(casadi_int ind) const
Get default input value.
virtual Sparsity get_sparsity_in(casadi_int i)
Get sparsity of a given input.
Function object.
Definition: function.hpp:60
const std::vector< std::string > & name_in() const
Get input scheme.
Definition: function.cpp:961
static Function create(FunctionInternal *node)
Create from node.
Definition: function.cpp:336
casadi_int n_out() const
Get the number of function outputs.
Definition: function.cpp:823
casadi_int n_in() const
Get the number of function inputs.
Definition: function.cpp:819
Function map(casadi_int n, const std::string &parallelization="serial") const
Create a mapped version of this function.
Definition: function.cpp:709
std::map< std::string, std::vector< std::string > > AuxOut
Definition: function.hpp:404
const std::vector< std::string > & name_out() const
Get output scheme.
Definition: function.cpp:965
Sparsity get_sparsity_in(casadi_int i) override
Retreive sparsities.
Definition: external.cpp:214
Sparsity get_sparsity_out(casadi_int i) override
Retreive sparsities.
Definition: external.cpp:226
bool get_diff_in(casadi_int i) override
Retreive differentiability.
Definition: external.cpp:266
bool any_symbol_found() const override
Any symbol found?
Definition: external.cpp:116
bool get_diff_out(casadi_int i) override
Retreive differentiability.
Definition: external.cpp:276
void init_external() override
Initialize members that are unique.
Definition: external.cpp:124
GenericExternal(const std::string &name, const Importer &li, const std::vector< std::string > config_args=std::vector< std::string >())
Constructor.
Definition: external.cpp:109
void init(const Dict &opts) override
Initialize.
Definition: external.cpp:326
bool has_jac_sparsity(casadi_int oind, casadi_int iind) const override
Return sparsity of Jacobian of an output respect to an input.
Definition: external.cpp:238
Sparsity get_jac_sparsity(casadi_int oind, casadi_int iind, bool symmetric) const override
Return sparsity of Jacobian of an output respect to an input.
Definition: external.cpp:250
void serialize_type(SerializingStream &s) const override
Serialize type information.
Definition: external.cpp:523
Importer.
Definition: importer.hpp:86
std::string library() const
Get library name.
Definition: importer.cpp:99
std::string meta_string(const std::string &cmd, casadi_int ind=-1) const
Get entry as a string.
Definition: importer.hpp:180
std::string body(const std::string &symname) const
Get the function body, if inlined.
Definition: importer.cpp:95
casadi_int meta_int(const std::string &cmd, casadi_int ind=-1) const
Get entry as an integer.
Definition: importer.hpp:203
std::vector< T > meta_vector(const std::string &cmd, casadi_int ind=-1) const
Get entry as a vector.
Definition: importer.hpp:188
bool has_meta(const std::string &cmd, casadi_int ind=-1) const
Does a meta entry exist?
Definition: importer.cpp:83
bool has_function(const std::string &symname) const
Definition: importer.cpp:75
bool inlined(const std::string &symname) const
Check if a function is inlined.
Definition: importer.cpp:91
signal_t get_function(const std::string &symname)
Get a function pointer for numerical evaluation.
Definition: importer.cpp:79
Base class for FunctionInternal and LinsolInternal.
void clear_mem()
Clear all memory (called from destructor)
Helper class for Serialization.
void version(const std::string &name, int v)
void pack(const Sparsity &e)
Serializes an object to the output stream.
General sparsity class.
Definition: sparsity.hpp:106
static Sparsity compressed(const std::vector< casadi_int > &v, bool order_rows=false)
Definition: sparsity.cpp:1325
The casadi namespace.
Definition: archiver.cpp:28
std::vector< casadi_int > range(casadi_int start, casadi_int stop, casadi_int step, casadi_int len)
Range function.
const casadi_int *(* sparsity_t)(casadi_int i)
Function pointer types for the C API.
std::vector< T > vector_tail(const std::vector< T > &v)
Return all but the first element of a vector.
int(* casadi_checkout_t)(void)
Function pointer types for the C API.
int(* diff_t)(casadi_int i)
Function pointer types for the C API.
const char *(* name_t)(casadi_int i)
Function pointer types for the C API.
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.
int(* eval_t)(const double **arg, double **res, casadi_int *iw, double *w, int)
Function pointer types for the C API.
casadi_int(* getint_t)(void)
Function pointer types for the C API.
int(* config_t)(int, const char **)
Function pointer types for the C API.
std::string str(const T &v)
String representation, any type.
GenericType::Dict Dict
C++ equivalent of Python's dict or MATLAB's struct.
void(* casadi_release_t)(int)
Function pointer types for the C API.
void(* signal_t)(void)
Function pointer types for the C API.
T * get_ptr(std::vector< T > &v)
Get a pointer to the data contained in the vector.
double(* default_t)(casadi_int i)
Function pointer types for the C API.
std::vector< T > reverse(const std::vector< T > &v)
Reverse a list.
Dict extract_from_dict(const Dict &d, const std::string &key, T &value)
int(* work_t)(casadi_int *sz_arg, casadi_int *sz_res, casadi_int *sz_iw, casadi_int *sz_w)
Function pointer types for the C API.
Function external(const std::string &name, const Importer &li, const Dict &opts)
Load a just-in-time compiled external function.
Definition: external.cpp:42