23 #ifndef CASADI_PLUGIN_INTERFACE_HPP
24 #define CASADI_PLUGIN_INTERFACE_HPP
26 #include "function_internal.hpp"
27 #include "global_options.hpp"
28 #include "serializing_stream.hpp"
29 #include "casadi_os.hpp"
30 #include <casadi/config.h>
31 #include <casadi/core/casadi_common.hpp>
41 casadi_assert(t!=0,
"Static function not implemented for plugin");
53 template<
class Derived>
76 static bool has_plugin(
const std::string& pname,
bool verbose=
false);
89 bool register_plugin=
true,
bool needs_lock=
true);
92 static handle_t
load_library(
const std::string& libname, std::string& resultpath,
105 template<
class Problem>
107 const std::string& pname, Problem problem);
130 template<
class Derived>
133 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
134 std::lock_guard<std::mutex> lock(Derived::mutex_solvers_);
138 if (Derived::solvers_.
find(pname) != Derived::solvers_.end()) {
144 (void)load_plugin(pname,
false,
false);
148 casadi_warning(ex.
what());
154 template<
class Derived>
156 const Options *op = getPlugin(pname).options;
157 casadi_assert(op!=
nullptr,
"Plugin \"" + pname +
"\" does not support options");
161 template<
class Derived>
164 casadi_assert(m,
"Plugin \"" + pname +
"\" does not support deserialize");
168 template<
class Derived>
175 int flag = regfcn(&plugin);
176 casadi_assert(flag==0,
"Registration of plugin failed.");
182 template<
class Derived>
184 std::string& resultpath,
bool global) {
187 casadi_error(
"WITH_DL option needed for dynamic loading");
191 std::string lib = SHARED_LIBRARY_PREFIX + libname + SHARED_LIBRARY_SUFFIX;
195 return open_shared_library(lib, search_paths, resultpath,
196 "PluginInterface::load_plugin", global);
201 template<
class Derived>
204 bool register_plugin,
bool needs_lock) {
206 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
211 if (Derived::solvers_.
find(pname) != Derived::solvers_.end()) {
212 casadi_warning(
"PluginInterface: Solver " + pname +
" is already in use. Ignored.");
223 casadi_error(
"WITH_DL option needed for dynamic loading");
229 std::string regName =
"casadi_register_" + Derived::infix_ +
"_" + pname;
231 std::string searchpath;
232 handle_t handle = load_library(
"casadi_" + Derived::infix_ +
"_" + pname, searchpath,
238 #pragma GCC diagnostic push
239 #pragma GCC diagnostic ignored "-Wcast-function-type"
241 reg =
reinterpret_cast<RegFcn
>(GetProcAddress(handle, TEXT(regName.c_str())));
243 #pragma GCC diagnostic pop
251 reg =
reinterpret_cast<RegFcn
>(dlsym(handle, regName.c_str()));
253 casadi_assert(reg!=
nullptr,
254 "PluginInterface::load_plugin: no \"" + regName +
"\" found in " + searchpath +
".");
257 Plugin plugin = pluginFromRegFcn(reg);
259 if (register_plugin) {
260 registerPlugin(plugin,
false);
268 template<
class Derived>
270 registerPlugin(pluginFromRegFcn(regfcn), needs_lock);
273 template<
class Derived>
276 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
281 typename std::map<std::string, Plugin>::iterator it=Derived::solvers_.find(plugin.
name);
282 casadi_assert(it==Derived::solvers_.end(),
283 "Solver " +
str(plugin.
name) +
" is already in use");
286 Derived::solvers_[plugin.
name] = plugin;
289 template<
class Derived>
293 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
294 std::lock_guard<std::mutex> lock(Derived::mutex_solvers_);
298 auto it=Derived::solvers_.find(pname);
301 if (it==Derived::solvers_.end()) {
302 load_plugin(pname,
true,
false);
303 it=Derived::solvers_.find(pname);
305 casadi_assert_dev(it!=Derived::solvers_.end());
309 template<
class Derived>
310 template<
class Problem>
313 const std::string& pname, Problem problem) {
316 if (!has_plugin(pname,
true)) {
317 casadi_error(
"Plugin '" + pname +
"' is not found.");
319 return getPlugin(pname).creator(fname, problem);
const char * what() const override
Display error.
Helper class for Serialization.
void unpack(Sparsity &e)
Reconstruct an object from the input stream.
Interface for accessing input and output data structures.
static bool has_plugin(const std::string &pname, bool verbose=false)
Check if a plugin is available or can be loaded.
static handle_t load_library(const std::string &libname, std::string &resultpath, bool global)
Load a library dynamically.
static Derived * instantiate(const std::string &fname, const std::string &pname, Problem problem)
void serialize_type(SerializingStream &s) const
Serialize type information.
int(* RegFcn)(Plugin *plugin)
static Plugin pluginFromRegFcn(RegFcn regfcn)
Instantiate a Plugin struct from a factory function.
static const Options & plugin_options(const std::string &pname)
Get the plugin options.
static Plugin & getPlugin(const std::string &pname)
Load and get the creator function.
static Deserialize plugin_deserialize(const std::string &pname)
Get the plugin deserialize_map.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
static void registerPlugin(RegFcn regfcn, bool needs_lock=true)
Register an integrator in the factory.
virtual const char * plugin_name() const =0
static Plugin load_plugin(const std::string &pname, bool register_plugin=true, bool needs_lock=true)
Load a plugin dynamically.
Base class for FunctionInternal and LinsolInternal.
Helper class for Serialization.
void pack(const Sparsity &e)
Serializes an object to the output stream.
ProtoFunction *(* Deserialize)(DeserializingStream &)
std::vector< casadi_int > find(const std::vector< T > &v)
find nonzeros
std::vector< std::string > get_search_paths()
std::string str(const T &v)
String representation, any type.
Options metadata for a class.