Permalink
Browse files

Merge branch 'develop' of github.com:casadi/casadi into release-3.3.0…

…-rc1
  • Loading branch information...
jgillis committed Sep 30, 2017
2 parents fa815e5 + f36675a commit 5d41c46df07306bcb20215486b1634604d174134
@@ -142,7 +142,8 @@ set(CASADI_INTERNAL
x_function.hpp # Base class for SXFunction and MXFunction
sx_function.hpp sx_function.cpp
mx_function.hpp mx_function.cpp
external.cpp
external_impl.hpp external.cpp
jit_function.hpp jit_function.cpp
linsol.cpp linsol_internal.hpp linsol_internal.cpp
rootfinder_impl.hpp rootfinder.cpp
integrator_impl.hpp integrator.cpp
@@ -348,126 +348,4 @@ namespace casadi {
return ret;
}
Function jit_function(const std::string& name,
const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
const std::string& body, const Dict& opts) {
// Pass empty vectors -> default values
std::vector<Sparsity> sparsity_in, sparsity_out;
return jit_function(name, name_in, name_out, sparsity_in, sparsity_out, body, opts);
}
Function jit_function(const std::string& name,
const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
const std::vector<Sparsity>& sparsity_in,
const std::vector<Sparsity>& sparsity_out,
const std::string& body, const Dict& opts) {
return Function::create(new JitFunction(name, name_in, name_out, sparsity_in,
sparsity_out, body), opts);
}
JitFunction::JitFunction(const std::string& name,
const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
const std::vector<Sparsity>& sparsity_in,
const std::vector<Sparsity>& sparsity_out,
const std::string& body) : FunctionInternal(name), body_(body) {
// Set sparsity
sparsity_in_ = sparsity_in;
sparsity_out_ = sparsity_out;
name_in_ = name_in;
name_out_ = name_out;
// Default options
jit_ = true; // override default
buffered_ = true;
enable_fd_ = true; // override default
}
Options JitFunction::options_
= {{&FunctionInternal::options_},
{{"buffered",
{OT_BOOL,
"Buffer the calls, user does not need to "}},
{"jac",
{OT_STRING,
"Function body for Jacobian"}},
{"hess",
{OT_STRING,
"Function body for Hessian"}}
}
};
void JitFunction::init(const Dict& opts) {
// Call the initialization method of the base class
FunctionInternal::init(opts);
// Read options
for (auto&& op : opts) {
if (op.first=="buffered") {
buffered_ = op.second;
} else if (op.first=="jac") {
jac_body_ = op.second.to_string();
} else if (op.first=="hess") {
hess_body_ = op.second.to_string();
}
}
// Arrays for holding inputs and outputs
if (buffered_) {
alloc_w(nnz_in() + nnz_out());
}
}
JitFunction::~JitFunction() {
}
void JitFunction::codegen_body(CodeGenerator& g) const {
// Add all input arguments as local variables
for (int i=0; i<n_in_; ++i) {
g.local(name_in_[i], "const casadi_real", "*");
if (buffered_) {
g << g.copy("*arg++", nnz_in(i), "w") << "\n"
<< name_in_[i] << " = w; w += " << nnz_in(i) << ";\n";
} else {
g << name_in_[i] << " = *arg++;\n";
}
}
// Add all output arguments as local variables
for (int i=0; i<n_out_; ++i) {
g.local(name_out_[i], "casadi_real", "*");
if (buffered_) {
g << name_out_[i] << " = w; w += " << nnz_out(i) << ";\n";
} else {
g << name_out_[i] << " = *res++;\n";
}
}
// Codegen function body
g << body_;
// Get results
for (int i=0; i<n_out_; ++i) {
if (buffered_) {
g << g.copy(name_out_[i], nnz_out(i), "*res++") << "\n";
}
}
}
bool JitFunction::has_jacobian() const {
return !jac_body_.empty();
}
Function JitFunction::get_jacobian(const std::string& name,
const std::vector<std::string>& inames,
const std::vector<std::string>& onames,
const Dict& opts) const {
// Create a JIT-function for the Jacobian
Dict jac_opts;
if (!hess_body_.empty()) jac_opts["jac"] = hess_body_;
return jit_function(name, inames, onames, jac_body_, jac_opts);
}
} // namespace casadi
@@ -48,49 +48,6 @@ namespace casadi {
CASADI_EXPORT Function external(const std::string& name, const Importer& compiler,
const Dict& opts=Dict());
///@{
/** \brief Create a just-in-time compiled function from a C language string
* The names and sparsity patterns of all the inputs and outputs must be provided.
* If sparsities are not provided, all inputs and outputs are assumed to be scalar.
* Only specify the function body, assuming that input and output nonzeros are
* stored in arrays with the specified naming convension.
* The data type used is 'casadi_real', which is typically equal to 'double` or
* another data type with the same API as 'double'.
*
* Inputs may be null pointers. This means that the all entries are zero.
* Outputs may be null points. This means that the corresponding result can be ignored.
*
* If an error occurs in the evaluation, issue "return 1;";
*
* The final generated function will have a structure similar to:
*
* int fname(const casadi_real** arg, casadi_real** res, int* iw,
casadi_real* w, void* mem) {
* const casadi_real *x1, *x2;
* casadi_real *r1, *r2;
* x1 = *arg++;
* x2 = *arg++;
* r1 = *res++;
* r2 = *res++;
* <FUNCTION_BODY>
* return 0;
* }
*
*/
CASADI_EXPORT Function
jit_function(const std::string& name,
const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
const std::string& body, const Dict& opts=Dict());
CASADI_EXPORT Function
jit_function(const std::string& name,
const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
const std::vector<Sparsity>& sparsity_in,
const std::vector<Sparsity>& sparsity_out,
const std::string& body, const Dict& opts=Dict());
///@}
} // namespace casadi
#endif // CASADI_EXTERNAL_HPP
@@ -171,65 +171,6 @@ namespace casadi {
void free_mem(void *mem) const override;
};
class CASADI_EXPORT JitFunction : public FunctionInternal {
public:
/** \brief Constructor */
JitFunction(const std::string& name,
const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
const std::vector<Sparsity>& sparsity_in,
const std::vector<Sparsity>& sparsity_out,
const std::string& body);
/** \brief Get type name */
std::string class_name() const override { return "JitFunction";}
/** \brief Destructor */
~JitFunction() override;
///@{
/** \brief Options */
static Options options_;
const Options& get_options() const override { return options_;}
///@}
/** \brief Initialize */
void init(const Dict& opts) override;
///@{
/** \brief Number of function inputs and outputs */
size_t get_n_in() override { return name_in_.size();}
size_t get_n_out() override { return name_out_.size();}
///@}
/** \brief Is codegen supported? */
bool has_codegen() const override { return true;}
/** \brief Generate code for the function body */
void codegen_body(CodeGenerator& g) const override;
///@{
/** \brief Jacobian of all outputs with respect to all inputs */
bool has_jacobian() const override;
Function get_jacobian(const std::string& name,
const std::vector<std::string>& inames,
const std::vector<std::string>& onames,
const Dict& opts) const override;
///@}
// Buffer the function calls
bool buffered_;
// Function body
std::string body_;
// Jacobian function body
std::string jac_body_;
// Hessian function body
std::string hess_body_;
};
} // namespace casadi
/// \endcond
@@ -32,6 +32,7 @@
#include "bspline.hpp"
#include "nlpsol.hpp"
#include "conic.hpp"
#include "jit_function.hpp"
#include <typeinfo>
#include <fstream>
@@ -46,6 +47,12 @@ namespace casadi {
"[" + this->class_name() + "] at " + CASADI_WHERE + ":\n"\
+ string(WHAT));
// Throw informative error message from constructor
#define THROW_ERROR_NOOBJ(FNAME, WHAT, CLASS_NAME) \
throw CasadiException("Error in Function::" FNAME " for '" + name + "' "\
"[" CLASS_NAME "] at " + CASADI_WHERE + ":\n"\
+ string(WHAT));
Function::Function() {
}
@@ -206,17 +213,48 @@ namespace casadi {
const vector<string>& name_in,
const vector<string>& name_out,
const Dict& opts) {
own(new SXFunction(name, ex_in, ex_out, name_in, name_out));
(*this)->construct(opts);
try {
own(new SXFunction(name, ex_in, ex_out, name_in, name_out));
(*this)->construct(opts);
} catch (exception& e) {
THROW_ERROR_NOOBJ("Function", e.what(), "SXFunction");
}
}
void Function::construct(const string& name,
const vector<MX>& ex_in, const vector<MX>& ex_out,
const vector<string>& name_in,
const vector<string>& name_out,
const Dict& opts) {
own(new MXFunction(name, ex_in, ex_out, name_in, name_out));
(*this)->construct(opts);
try {
own(new MXFunction(name, ex_in, ex_out, name_in, name_out));
(*this)->construct(opts);
} catch (exception& e) {
THROW_ERROR_NOOBJ("Function", e.what(), "MXFunction");
}
}
Function Function::jit(const std::string& name, const std::string& body,
const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
const Dict& opts) {
// Pass empty vectors -> default values
std::vector<Sparsity> sparsity_in, sparsity_out;
return jit(name, body, name_in, name_out, sparsity_in, sparsity_out, opts);
}
Function Function::jit(const std::string& name, const std::string& body,
const std::vector<std::string>& name_in,
const std::vector<std::string>& name_out,
const std::vector<Sparsity>& sparsity_in,
const std::vector<Sparsity>& sparsity_out,
const Dict& opts) {
try {
return create(new JitFunction(name, body, name_in, name_out,
sparsity_in, sparsity_out), opts);
} catch (exception& e) {
THROW_ERROR_NOOBJ("jit", e.what(), "JitFunction");
}
}
Function Function::expand() const {
@@ -561,24 +599,40 @@ namespace casadi {
Function Function::conditional(const string& name, const vector<Function>& f,
const Function& f_def, const Dict& opts) {
return create(new Switch(name, f, f_def), opts);
try {
return create(new Switch(name, f, f_def), opts);
} catch (exception& e) {
THROW_ERROR_NOOBJ("conditional", e.what(), "Switch");
}
}
Function Function::bspline(const std::string &name,
const std::vector< std::vector<double> >& knots, const vector<double>& coeffs,
const vector<int>& degree, int m, const Dict& opts) {
return BSpline::create(name, knots, coeffs, degree, m, opts);
const std::vector< std::vector<double> >& knots,
const vector<double>& coeffs, const vector<int>& degree, int m, const Dict& opts) {
try {
return BSpline::create(name, knots, coeffs, degree, m, opts);
} catch (exception& e) {
THROW_ERROR_NOOBJ("bspline", e.what(), "BSpline");
}
}
Function Function::bspline_dual(const std::string &name,
const std::vector< std::vector<double> >& knots, const vector<double>& x,
const vector<int>& degree, int m, bool reverse, const Dict& opts) {
return BSplineDual::create(name, knots, x, degree, m, reverse, opts);
const std::vector< std::vector<double> >& knots, const vector<double>& x,
const vector<int>& degree, int m, bool reverse, const Dict& opts) {
try {
return BSplineDual::create(name, knots, x, degree, m, reverse, opts);
} catch (exception& e) {
THROW_ERROR_NOOBJ("bspline_dual", e.what(), "BSplineDual");
}
}
Function Function::if_else(const string& name, const Function& f_true,
const Function& f_false, const Dict& opts) {
return create(new Switch(name, vector<Function>(1, f_false), f_true), opts);
try {
return create(new Switch(name, vector<Function>(1, f_false), f_true), opts);
} catch (exception& e) {
THROW_ERROR_NOOBJ("if_else", e.what(), "Switch");
}
}
int Function::n_in() const {
Oops, something went wrong.

0 comments on commit 5d41c46

Please sign in to comment.