List of all members | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Protected Attributes
casadi::ClangCompiler Class Reference

'clang' plugin for Importer More...

#include <clang_compiler.hpp>

Detailed Description

Author
Joris Gillis
Date
2015

Interface to the JIT compiler CLANG

Extra doc: https://github.com/casadi/casadi/wiki/L_21v


List of available options
IdTypeDescription
flagsOT_STRINGVECTORCompile flags for the JIT compiler. Default: None
include_pathOT_STRINGInclude paths for the JIT compiler. The include directory shipped with CasADi will be automatically appended.


List of available options
IdTypeDescriptionUsed in
flagsOT_STRINGVECTORCompile flags for the JIT compiler. Default: Nonecasadi::ClangCompiler
include_pathOT_STRINGInclude paths for the JIT compiler. The include directory shipped with CasADi will be automatically appended.casadi::ClangCompiler
verboseOT_BOOLVerbose evaluation – for debuggingcasadi::ImporterInternal

Definition at line 83 of file clang_compiler.hpp.

Inheritance diagram for casadi::ClangCompiler:
Inheritance graph
[legend]
Collaboration diagram for casadi::ClangCompiler:
Collaboration graph
[legend]

Public Types

typedef ImporterInternal *(* Creator) (const std::string &name)
 
using weak_ref_type = WeakRefInternal
 
typedef int(* RegFcn) (Plugin *plugin)
 

Public Member Functions

 ClangCompiler (const std::string &name)
 Constructor. More...
 
 ~ClangCompiler () override
 Destructor. More...
 
void init (const Dict &opts) override
 Initialize. More...
 
const char * plugin_name () const override
 Get name of plugin. More...
 
std::string class_name () const override
 Get type name. More...
 
signal_t get_function (const std::string &symname) override
 Get a function pointer for numerical evaluation. More...
 
void disp (std::ostream &stream, bool more) const override
 Print. More...
 
void construct (const Dict &opts)
 Construct. More...
 
virtual void finalize ()
 
bool has_function (const std::string &symname) const
 Get a function pointer for numerical evaluation. More...
 
bool has_meta (const std::string &cmd, casadi_int ind=-1) const
 Does an entry exist? More...
 
std::string get_meta (const std::string &cmd, casadi_int ind=-1) const
 Get entry as a text. More...
 
void read_meta (std::istream &file, casadi_int &offset)
 Get meta information. More...
 
void read_external (const std::string &sym, bool inlined, std::istream &file, casadi_int &offset)
 Get an external function declaration. More...
 
bool inlined (const std::string &symname) const
 
std::string body (const std::string &symname) const
 Get the function body, if inlined. More...
 
virtual std::string library () const
 Get library name. More...
 
virtual bool can_have_meta () const
 Can meta information be read? More...
 
std::string to_text (const std::string &cmd, casadi_int ind=-1) const
 Get entry as a text. More...
 
void serialize (SerializingStream &s) const
 
virtual void serialize_type (SerializingStream &s) const
 
virtual void serialize_body (SerializingStream &s) const
 
casadi_int getCount () const
 Get the reference count. More...
 
std::string debug_repr (const SharedObjectInternal *) const
 
GenericWeakRef< SharedObject, SharedObjectInternal > * weak ()
 Get a weak reference to the object. More...
 
virtual void deps_version_check (const std::string &stage) const
 

Static Public Member Functions

static ImporterInternalcreator (const std::string &name)
 Create a new JIT function. More...
 
static std::vector< std::pair< std::string, bool > > getIncludes (const std::string &file, const std::string &path)
 
static std::string shortname ()
 Short name. More...
 
static std::string indexed (const std::string &cmd, casadi_int ind)
 
static ImporterInternaldeserialize (DeserializingStream &s)
 
static bool has_plugin (const std::string &pname, bool verbose=false)
 Check if a plugin is available or can be loaded. More...
 
static const Optionsplugin_options (const std::string &pname)
 Get the plugin options. More...
 
static Deserialize plugin_deserialize (const std::string &pname)
 Get the plugin deserialize_map. More...
 
static Plugin pluginFromRegFcn (RegFcn regfcn)
 Instantiate a Plugin struct from a factory function. More...
 
static Plugin load_plugin (const std::string &pname, bool register_plugin=true, bool needs_lock=true)
 Load a plugin dynamically. More...
 
static handle_t load_library (const std::string &libname, std::string &resultpath, bool global)
 Load a library dynamically. More...
 
static void registerPlugin (const Plugin &plugin, bool needs_lock=true)
 Register an integrator in the factory. More...
 
static void registerPlugin (RegFcn regfcn, bool needs_lock=true)
 Register an integrator in the factory. More...
 
static Plugin & getPlugin (const std::string &pname)
 Load and get the creator function. More...
 
static ImporterInternalinstantiate (const std::string &fname, const std::string &pname, Problem problem)
 

Public Attributes

std::string include_path_
 
std::vector< std::string > flags_
 
std::string name_
 C filename. More...
 
std::map< std::string, std::pair< casadi_int, std::string > > meta_
 Meta data. More...
 
std::map< std::string, std::pair< bool, std::string > > external_
 External functions. More...
 
bool verbose_
 Verbose – for debugging purposes. More...
 

Static Public Attributes

static const std::string meta_doc
 A documentation string. More...
 
static std::map< std::string, Plugin > solvers_
 Collection of solvers. More...
 
static const std::string infix_ = "importer"
 Infix. More...
 

Protected Member Functions

void initSingleton ()
 
void destroySingleton ()
 
shared_from_this ()
 Get a shared object from the current internal object. More...
 
const B shared_from_this () const
 Get a shared object from the current internal object. More...
 

Protected Attributes

clang::EmitLLVMOnlyAction * act_
 
llvm::ExecutionEngine * executionEngine_
 
llvm::LLVMContext * context_
 
llvm::raw_ostream * myerr_
 
llvm::Module * module_
 
static const Options options_
 Options. More...
 
const Optionsget_options () const override
 Options. More...
 

Member Typedef Documentation

◆ Creator

typedef ImporterInternal*(* casadi::ImporterInternal::Creator) (const std::string &name)
inherited

Definition at line 66 of file importer_internal.hpp.

◆ RegFcn

typedef int(* casadi::PluginInterface< ImporterInternal >::RegFcn) (Plugin *plugin)
inherited

Definition at line 73 of file plugin_interface.hpp.

◆ weak_ref_type

Definition at line 152 of file shared_object.hpp.

Constructor & Destructor Documentation

◆ ClangCompiler()

casadi::ClangCompiler::ClangCompiler ( const std::string &  name)
explicit

Definition at line 60 of file clang_compiler.cpp.

60  :
61  ImporterInternal(name) {
62 
63  myerr_ = nullptr;
64  executionEngine_ = nullptr;
65  context_ = nullptr;
66  act_ = nullptr;
67  }
clang::EmitLLVMOnlyAction * act_
llvm::raw_ostream * myerr_
llvm::LLVMContext * context_
llvm::ExecutionEngine * executionEngine_
ImporterInternal(const std::string &name)
Constructor.

References act_, context_, executionEngine_, and myerr_.

◆ ~ClangCompiler()

casadi::ClangCompiler::~ClangCompiler ( )
override

Definition at line 69 of file clang_compiler.cpp.

69  {
70  if (act_) delete act_; // NOLINT(readability-delete-null-pointer)
71  if (myerr_) delete myerr_; // NOLINT(readability-delete-null-pointer)
72  if (executionEngine_) delete executionEngine_; // NOLINT(readability-delete-null-pointer)
73  if (context_) delete context_; // NOLINT(readability-delete-null-pointer)
74  }

References act_, context_, executionEngine_, and myerr_.

Member Function Documentation

◆ body()

std::string casadi::ImporterInternal::body ( const std::string &  symname) const
inherited

Definition at line 306 of file importer_internal.cpp.

306  {
307  auto it = external_.find(symname);
308  casadi_assert_dev(it!=external_.end() && it->second.first);
309  return it->second.second;
310  }
std::map< std::string, std::pair< bool, std::string > > external_
External functions.

References casadi::ImporterInternal::external_.

◆ can_have_meta()

virtual bool casadi::ImporterInternal::can_have_meta ( ) const
inlinevirtualinherited

Reimplemented in casadi::DllLibrary.

Definition at line 142 of file importer_internal.hpp.

142 { return true;}

Referenced by casadi::ImporterInternal::init().

◆ class_name()

std::string casadi::ClangCompiler::class_name ( ) const
inlineoverridevirtual

Extra doc: https://github.com/casadi/casadi/wiki/L_219

Reimplemented from casadi::ImporterInternal.

Definition at line 113 of file clang_compiler.hpp.

113 { return "ClangCompiler";}

◆ construct()

void casadi::ImporterInternal::construct ( const Dict opts)
inherited

Prepares the function for evaluation

Extra doc: https://github.com/casadi/casadi/wiki/L_21b

Definition at line 57 of file importer_internal.cpp.

57  {
58  // Sanitize dictionary is needed
59  if (!Options::is_sane(opts)) {
60  // Call recursively
62  return;
63  }
64 
65  // Make sure all options exist
66  get_options().check(opts);
67 
68  // Initialize object
69  init(opts);
70 
71  // Revisit class hierarchy in reverse order
72  finalize();
73  }
virtual void init(const Dict &opts)
Initialize.
void construct(const Dict &opts)
Construct.
virtual const Options & get_options() const
Options.
static bool is_sane(const Dict &opts)
Is the dictionary sane.
Definition: options.cpp:169
static Dict sanitize(const Dict &opts, bool top_level=true)
Sanitize a options dictionary.
Definition: options.cpp:173
void check(const Dict &opts) const
Check if options exist.
Definition: options.cpp:240

References casadi::Options::check(), casadi::ImporterInternal::finalize(), casadi::ImporterInternal::get_options(), casadi::ImporterInternal::init(), casadi::Options::is_sane(), and casadi::Options::sanitize().

Referenced by casadi::Importer::create().

◆ creator()

static ImporterInternal* casadi::ClangCompiler::creator ( const std::string &  name)
inlinestatic

Definition at line 90 of file clang_compiler.hpp.

90  {
91  return new ClangCompiler(name);
92  }
ClangCompiler(const std::string &name)
Constructor.

Referenced by casadi::casadi_register_importer_clang().

◆ debug_repr()

std::string casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::debug_repr ( const Internal *  i) const
inherited

Definition at line 62 of file generic_shared_internal.hpp.

175  {
176  // Note: i != this because of something something multiple inheritance
177  return str( (casadi_int)(i)) + "/" + static_cast<const Internal*>(this)->class_name();
178  }
std::string str(const T &v)
String representation, any type.

◆ deps_version_check()

virtual void casadi::PluginInterface< ImporterInternal >::deps_version_check ( const std::string &  stage) const
inlinevirtualinherited

Definition at line 112 of file plugin_interface.hpp.

112 {}

◆ deserialize()

ImporterInternal * casadi::ImporterInternal::deserialize ( DeserializingStream s)
staticinherited

Definition at line 339 of file importer_internal.cpp.

339  {
340  std::string class_name;
341  s.unpack("ImporterInternal::type", class_name);
342  if (class_name=="DllLibrary") {
343  return DllLibrary::deserialize(s);
344  } else {
345  casadi_error("Cannot deserialize type '" + class_name + "'");
346  }
347  }
static ImporterInternal * deserialize(DeserializingStream &s)
std::string class_name() const override
Get type name.

References casadi::ImporterInternal::class_name(), casadi::DllLibrary::deserialize(), and casadi::DeserializingStream::unpack().

Referenced by casadi::Importer::deserialize().

◆ destroySingleton()

void casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::destroySingleton ( )
inlineprotectedinherited

Called in the destructor of singletons

Definition at line 77 of file generic_shared_internal.hpp.

77  {
78  static_cast<Internal*>(this)->count--;
79  }

◆ disp()

void casadi::ImporterInternal::disp ( std::ostream &  stream,
bool  more 
) const
overridevirtualinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_21a

Implements casadi::SharedObjectInternal.

Definition at line 38 of file importer_internal.cpp.

38  {
39  }

◆ finalize()

virtual void casadi::ImporterInternal::finalize ( )
inlinevirtualinherited

Reimplemented in casadi::DllLibrary.

Definition at line 88 of file importer_internal.hpp.

88 {}

Referenced by casadi::ImporterInternal::construct().

◆ get_function()

signal_t casadi::ClangCompiler::get_function ( const std::string &  symname)
overridevirtual

Reimplemented from casadi::ImporterInternal.

Definition at line 239 of file clang_compiler.cpp.

239  {
240  llvm::Function* f = module_->getFunction(symname);
241  if (f) {
242  return reinterpret_cast<signal_t>(executionEngine_->getPointerToFunction(f));
243  } else {
244  return nullptr;
245  }
246  }
void(* signal_t)(void)
Function pointer types for the C API.

References executionEngine_, and module_.

◆ get_meta()

std::string casadi::ImporterInternal::get_meta ( const std::string &  cmd,
casadi_int  ind = -1 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_21f

Definition at line 290 of file importer_internal.cpp.

290  {
291  if (ind>=0) return get_meta(indexed(cmd, ind));
292  casadi_assert(has_meta(cmd), "No such command: " + cmd);
293  return meta_.at(cmd).second;
294  }
std::map< std::string, std::pair< casadi_int, std::string > > meta_
Meta data.
std::string get_meta(const std::string &cmd, casadi_int ind=-1) const
Get entry as a text.
bool has_meta(const std::string &cmd, casadi_int ind=-1) const
Does an entry exist?
static std::string indexed(const std::string &cmd, casadi_int ind)

References casadi::ImporterInternal::has_meta(), casadi::ImporterInternal::indexed(), and casadi::ImporterInternal::meta_.

◆ get_options()

const Options& casadi::ClangCompiler::get_options ( ) const
inlineoverridevirtual

Reimplemented from casadi::ImporterInternal.

Definition at line 100 of file clang_compiler.hpp.

100 { return options_;}
static const Options options_
Options.

◆ getCount()

Definition at line 60 of file generic_shared_internal.hpp.

205  {
206  return static_cast<const Internal*>(this)->count;
207  }

◆ getIncludes()

std::vector< std::pair< std::string, bool > > casadi::ClangCompiler::getIncludes ( const std::string &  file,
const std::string &  path 
)
static

Definition at line 248 of file clang_compiler.cpp.

249  {
250  // File separator
251 #ifdef _WIN32
252  const char sep = '\\';
253 #else // _WIN32
254  const char sep = '/';
255 #endif // _WIN32
256 
257  // Return value
258  std::vector<std::pair<std::string, bool> > ret;
259 
260  // Read line-by-line
261  auto setup_file_ptr = Filesystem::ifstream_ptr(path + sep + file);
262  std::istream& setup_file = *setup_file_ptr;
263 
264  std::string line;
265  while (std::getline(setup_file, line)) {
266  // Skip empty lines
267  if (line.empty()) continue;
268 
269  // Check if framework
270  size_t loc = line.find(" (framework directory)");
271  bool isframework = loc != std::string::npos;
272  if (isframework) {
273  // Truncate path
274  line = line.substr(0, loc);
275  }
276 
277  // Check if the path is absolute or relative
278 #ifdef _WIN32
279  bool relative = PathIsRelative(TEXT(line.c_str()));
280 #else // _WIN32
281  bool relative = line.at(0)!=sep;
282 #endif // _WIN32
283 
284  if (relative) {
285  // Relative path, make absolute
286  ret.push_back(std::make_pair(path + sep + line, isframework));
287  } else {
288  // Absolute path
289  ret.push_back(std::make_pair(line, isframework));
290  }
291  }
292 
293  return ret;
294  }
static std::unique_ptr< std::istream > ifstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::in, bool fail=true)
Definition: filesystem.cpp:135
std::vector< casadi_int > path(const std::vector< casadi_int > &map, casadi_int i_start)

References casadi::Filesystem::ifstream_ptr(), and casadi::path().

Referenced by init().

◆ getPlugin()

PluginInterface< ImporterInternal >::Plugin & casadi::PluginInterface< ImporterInternal >::getPlugin ( const std::string &  pname)
staticinherited

Definition at line 102 of file plugin_interface.hpp.

295  {
296 
297 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
298  std::lock_guard<std::mutex> lock(Derived::mutex_solvers_);
299 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
300 
301  // Check if the solver has been loaded
302  auto it=Derived::solvers_.find(pname);
303 
304  // Load the solver if needed
305  if (it==Derived::solvers_.end()) {
306  load_plugin(pname, true, false);
307  it=Derived::solvers_.find(pname);
308  }
309  casadi_assert_dev(it!=Derived::solvers_.end());
310  return it->second;
311  }
static Plugin load_plugin(const std::string &pname, bool register_plugin=true, bool needs_lock=true)
Load a plugin dynamically.

◆ has_function()

bool casadi::ImporterInternal::has_function ( const std::string &  symname) const
inherited

Definition at line 217 of file importer_internal.cpp.

217  {
218  // Check if in meta information
219  if (external_.find(symname)!=external_.end()) return true;
220 
221  // Convert to a dummy function pointer
222  return const_cast<ImporterInternal*>(this)->get_function(symname)!=nullptr;
223  }
virtual signal_t get_function(const std::string &symname)
Get a function pointer for numerical evaluation.

References casadi::ImporterInternal::external_, and casadi::ImporterInternal::get_function().

◆ has_meta()

bool casadi::ImporterInternal::has_meta ( const std::string &  cmd,
casadi_int  ind = -1 
) const
inherited

Extra doc: https://github.com/casadi/casadi/wiki/L_21e

Definition at line 296 of file importer_internal.cpp.

296  {
297  if (ind>=0) return has_meta(indexed(cmd, ind));
298  return meta_.find(cmd) != meta_.end();
299  }

References casadi::ImporterInternal::indexed(), and casadi::ImporterInternal::meta_.

Referenced by casadi::ImporterInternal::get_meta().

◆ has_plugin()

bool casadi::PluginInterface< ImporterInternal >::has_plugin ( const std::string &  pname,
bool  verbose = false 
)
staticinherited

Definition at line 76 of file plugin_interface.hpp.

134  {
135 
136 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
137  std::lock_guard<std::mutex> lock(Derived::mutex_solvers_);
138 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
139 
140  // Quick return if available
141  if (Derived::solvers_.find(pname) != Derived::solvers_.end()) {
142  return true;
143  }
144 
145  // Try loading the plugin
146  try {
147  (void)load_plugin(pname, false, false);
148  return true;
149  } catch (CasadiException& ex) {
150  if (verbose) {
151  casadi_warning(ex.what());
152  }
153  return false;
154  }
155  }
std::vector< casadi_int > find(const std::vector< T > &v)
find nonzeros

◆ indexed()

static std::string casadi::ImporterInternal::indexed ( const std::string &  cmd,
casadi_int  ind 
)
inlinestaticinherited

Convert indexed command

Definition at line 150 of file importer_internal.hpp.

150  {
151  std::stringstream ss;
152  ss << cmd << "[" << ind << "]";
153  return ss.str();
154  }

Referenced by casadi::ImporterInternal::get_meta(), and casadi::ImporterInternal::has_meta().

◆ init()

void casadi::ClangCompiler::init ( const Dict opts)
overridevirtual

Reimplemented from casadi::ImporterInternal.

Definition at line 88 of file clang_compiler.cpp.

88  {
89  // Base class
91 
92  // Read options
93  for (auto&& op : opts) {
94  if (op.first=="include_path") {
95  include_path_ = op.second.to_string();
96  } else if (op.first=="flags") {
97  flags_ = op.second;
98  }
99  }
100 
101  // Arguments to pass to the clang frontend
102  std::vector<const char *> args(1, name_.c_str());
103  for (auto&& f : flags_) {
104  args.push_back(f.c_str());
105  }
106 
107  // Create the compiler instance
108  clang::CompilerInstance compInst;
109 
110  // A symbol in the DLL
111  void *addr = reinterpret_cast<void*>(&casadi_register_importer_clang);
112 
113  // Get runtime include path
114  std::string jit_include;
115 #ifdef _WIN32
116  char buffer[MAX_PATH];
117  HMODULE hm = NULL;
118  if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
119  GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
120  (LPCSTR)addr, &hm)) {
121  casadi_error("GetModuleHandle failed");
122  }
123  GetModuleFileNameA(hm, buffer, sizeof(buffer));
124  PathRemoveFileSpecA(buffer);
125  jit_include = buffer;
126 #else // _WIN32
127  Dl_info dl_info;
128  if (!dladdr(addr, &dl_info)) {
129  casadi_error("dladdr failed");
130  }
131  jit_include = dl_info.dli_fname;
132  jit_include = jit_include.substr(0, jit_include.find_last_of('/'));
133 #endif // _WIN32
134  jit_include += filesep() + "casadi" + filesep() + "jit";
135 
136 #if 0
137  // Initialize target info with the default triple for our platform.
138  auto targetoptions = std::make_shared<clang::Taroptions>();
139  targetoptions->Triple = llvm::sys::getDefaultTargetTriple();
140  clang::TargetInfo *targetInfo =
141  clang::TargetInfo::CreateTargetInfo(compInst.get_diagnostics(), targetoptions);
142  compInst.setTarget(targetInfo);
143 #endif
144 
145  // The compiler invocation needs a DiagnosticsEngine so it can report problems
146  clang::DiagnosticOptions* diagOpts = new clang::DiagnosticOptions();
147  myerr_ = new llvm::raw_os_ostream(uerr());
148  clang::TextDiagnosticPrinter *diagClient = new clang::TextDiagnosticPrinter(*myerr_, diagOpts);
149 
150  clang::DiagnosticIDs* diagID = new clang::DiagnosticIDs();
151  // This object takes ownerships of all three passed-in pointers
152  clang::DiagnosticsEngine diags(diagID, diagOpts, diagClient);
153 
154  // Create the compiler invocation
155  #if LLVM_VERSION_MAJOR >= 4
156  std::shared_ptr<clang::CompilerInvocation> compInv(new clang::CompilerInvocation());
157  #else
158  clang::CompilerInvocation* compInv = new clang::CompilerInvocation();
159  #endif
160  #if LLVM_VERSION_MAJOR >= 5
161  clang::CompilerInvocation::CreateFromArgs(*compInv, args, diags);
162  #else
163  clang::CompilerInvocation::CreateFromArgs(*compInv, &args[0],
164  &args[0] + args.size(), diags);
165  #endif
166  compInst.setInvocation(compInv);
167 
168  // Get ready to report problems
169  compInst.createDiagnostics();
170  if (!compInst.hasDiagnostics())
171  casadi_error("Cannot create diagnostics");
172 
173  // Set resource directory
174  std::string resourcedir = jit_include + filesep() + "clang" + filesep() + CLANG_VERSION_STRING;
175  compInst.getHeaderSearchOpts().ResourceDir = resourcedir;
176 
177  // Read the system includes (C or C++)
178  std::vector<std::pair<std::string, bool> >
179  system_include = getIncludes("system_includes.txt", jit_include);
180  for (auto i=system_include.begin(); i!=system_include.end(); ++i) {
181  compInst.getHeaderSearchOpts().AddPath(i->first,
182  clang::frontend::System, i->second, false);
183  }
184 
185  // Read the system includes (C only)
186  system_include = getIncludes("csystem_includes.txt", jit_include);
187  for (auto i=system_include.begin(); i!=system_include.end(); ++i) {
188  compInst.getHeaderSearchOpts().AddPath(i->first,
189  clang::frontend::CSystem, i->second, false);
190  }
191 
192  // Read the system includes (C++ only)
193  system_include = getIncludes("cxxsystem_includes.txt", jit_include);
194  for (auto i=system_include.begin(); i!=system_include.end(); ++i) {
195  compInst.getHeaderSearchOpts().AddPath(i->first,
196  clang::frontend::CXXSystem, i->second, false);
197  }
198 
199  // Search path
200  std::stringstream paths;
201  paths << include_path_ << pathsep();
202  std::string path;
203  while (std::getline(paths, path, pathsep())) {
204  compInst.getHeaderSearchOpts().AddPath(path, clang::frontend::System, false, false);
205  }
206 
207  // Create an LLVM context (NOTE: should use a static context instead?)
208  context_ = new llvm::LLVMContext();
209 
210  // Create an action and make the compiler instance carry it out
211  act_ = new clang::EmitLLVMOnlyAction(context_);
212  if (!compInst.ExecuteAction(*act_))
213  casadi_error("Cannot execute action");
214 
215  // Grab the module built by the EmitLLVMOnlyAction
216  #if LLVM_VERSION_MAJOR>=4 || (LLVM_VERSION_MAJOR==3 && LLVM_VERSION_MINOR>=5)
217  std::unique_ptr<llvm::Module> module = act_->takeModule();
218  module_ = module.get();
219  #else
220  llvm::Module* module = act_->takeModule();
221  module_ = module;
222  #endif
223 
224  llvm::InitializeNativeTarget();
225  llvm::InitializeNativeTargetAsmPrinter();
226 
227  // Create the JIT. This takes ownership of the module.
228  std::string ErrStr;
230  llvm::EngineBuilder(std::move(module)).setEngineKind(llvm::EngineKind::JIT)
231  .setErrorStr(&ErrStr).create();
232  if (!executionEngine_) {
233  casadi_error("Could not create ExecutionEngine: " + ErrStr);
234  }
235 
236  executionEngine_->finalizeObject();
237  }
static std::vector< std::pair< std::string, bool > > getIncludes(const std::string &file, const std::string &path)
std::vector< std::string > flags_
std::string name_
C filename.
std::ostream & uerr()
std::string filesep()
Definition: casadi_os.cpp:71
int CASADI_IMPORTER_CLANG_EXPORT casadi_register_importer_clang(ImporterInternal::Plugin *plugin)
char pathsep()
Definition: casadi_os.cpp:64

References act_, casadi::casadi_register_importer_clang(), context_, executionEngine_, casadi::filesep(), flags_, getIncludes(), include_path_, casadi::ImporterInternal::init(), module_, myerr_, casadi::ImporterInternal::name_, casadi::path(), casadi::pathsep(), and casadi::uerr().

◆ initSingleton()

void casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::initSingleton ( )
inlineprotectedinherited

Called in the constructor of singletons to avoid that the counter reaches zero

Definition at line 71 of file generic_shared_internal.hpp.

71  {
72  casadi_assert_dev(static_cast<Internal*>(this)->count==0);
73  static_cast<Internal*>(this)->count++;
74  }

◆ inlined()

bool casadi::ImporterInternal::inlined ( const std::string &  symname) const
inherited

Definition at line 301 of file importer_internal.cpp.

301  {
302  auto it = external_.find(symname);
303  return it!=external_.end() && it->second.first;
304  }

References casadi::ImporterInternal::external_.

Referenced by casadi::ImporterInternal::init(), and casadi::ImporterInternal::read_external().

◆ instantiate()

ImporterInternal * casadi::PluginInterface< ImporterInternal >::instantiate ( const std::string &  fname,
const std::string &  pname,
Problem  problem 
)
staticinherited

Definition at line 106 of file plugin_interface.hpp.

317  {
318 
319  // Assert the plugin exists (needed for adaptors)
320  if (!has_plugin(pname, true)) {
321  casadi_error("Plugin '" + pname + "' is not found.");
322  }
323  return getPlugin(pname).creator(fname, problem);
324  }
static bool has_plugin(const std::string &pname, bool verbose=false)
Check if a plugin is available or can be loaded.
static Plugin & getPlugin(const std::string &pname)
Load and get the creator function.

◆ library()

std::string casadi::ImporterInternal::library ( ) const
virtualinherited

Reimplemented in casadi::ShellCompiler, and casadi::DllLibrary.

Definition at line 312 of file importer_internal.cpp.

312  {
313  casadi_error("library not implemented.");
314  }

◆ load_library()

handle_t casadi::PluginInterface< ImporterInternal >::load_library ( const std::string &  libname,
std::string &  resultpath,
bool  global 
)
staticinherited

Definition at line 92 of file plugin_interface.hpp.

187  {
188 
189 #ifndef WITH_DL
190  casadi_error("WITH_DL option needed for dynamic loading");
191 #else // WITH_DL
192 
193  // Get the name of the shared library
194  std::string lib = std::string(CasadiMeta::shared_library_prefix()) + libname +
195  CasadiMeta::shared_library_suffix();
196 
197  // Build up search paths;
198  std::vector<std::string> search_paths = get_search_paths();
199  return open_shared_library(lib, search_paths, resultpath,
200  "PluginInterface::load_plugin", global);
201 
202 #endif // WITH_DL
203  }
std::vector< std::string > get_search_paths()
Definition: casadi_os.cpp:79

◆ load_plugin()

PluginInterface< ImporterInternal >::Plugin casadi::PluginInterface< ImporterInternal >::load_plugin ( const std::string &  pname,
bool  register_plugin = true,
bool  needs_lock = true 
)
staticinherited

Definition at line 88 of file plugin_interface.hpp.

208  {
209 
210 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
211  casadi::conditional_lock_guard<std::mutex> lock(Derived::mutex_solvers_, needs_lock);
212 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
213 
214  // Issue warning and quick return if already loaded
215  if (Derived::solvers_.find(pname) != Derived::solvers_.end()) {
216  casadi_warning("PluginInterface: Solver " + pname + " is already in use. Ignored.");
217  return Plugin();
218  }
219 
220  // Logger singletons are lazily instantiated on first uout()/uerr() calls
221  // This instantation may lead to a data race with potential instatiations in plugin
222  // To be safe, trigger instantatin before any plugin loading
223  uout();
224  uerr();
225 
226 #ifndef WITH_DL
227  casadi_error("WITH_DL option needed for dynamic loading");
228 #else // WITH_DL
229  // Retrieve the registration function
230  RegFcn reg;
231 
232  // Load the dll
233  std::string regName = "casadi_register_" + Derived::infix_ + "_" + pname;
234 
235  std::string searchpath;
236  handle_t handle = load_library("casadi_" + Derived::infix_ + "_" + pname, searchpath,
237  false);
238 
239 #ifdef _WIN32
240 
241 #if __GNUC__
242 #pragma GCC diagnostic push
243 #pragma GCC diagnostic ignored "-Wcast-function-type"
244 #endif
245  reg = reinterpret_cast<RegFcn>(GetProcAddress(handle, TEXT(regName.c_str())));
246 #if __GNUC__
247 #pragma GCC diagnostic pop
248 #endif
249 
250 #else // _WIN32
251  // Reset error
252  dlerror();
253 
254  // Load creator
255  reg = reinterpret_cast<RegFcn>(dlsym(handle, regName.c_str()));
256 #endif // _WIN32
257  casadi_assert(reg!=nullptr,
258  "PluginInterface::load_plugin: no \"" + regName + "\" found in " + searchpath + ".");
259 
260  // Create a temporary struct
261  Plugin plugin = pluginFromRegFcn(reg);
262  // Register the plugin
263  if (register_plugin) {
264  registerPlugin(plugin, false);
265  }
266 
267  return plugin;
268 
269 #endif // WITH_DL
270  }
static handle_t load_library(const std::string &libname, std::string &resultpath, bool global)
Load a library dynamically.
static Plugin pluginFromRegFcn(RegFcn regfcn)
Instantiate a Plugin struct from a factory function.
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
void * handle_t
Definition: casadi_os.hpp:109
std::ostream & uout()

◆ plugin_deserialize()

Deserialize casadi::PluginInterface< ImporterInternal >::plugin_deserialize ( const std::string &  pname)
staticinherited

Definition at line 82 of file plugin_interface.hpp.

165  {
166  Deserialize m = getPlugin(pname).deserialize;
167  casadi_assert(m, "Plugin \"" + pname + "\" does not support deserialize");
168  return m;
169  }
ProtoFunction *(* Deserialize)(DeserializingStream &)

◆ plugin_name()

const char* casadi::ClangCompiler::plugin_name ( ) const
inlineoverridevirtual

Reimplemented from casadi::ImporterInternal.

Definition at line 110 of file clang_compiler.hpp.

110 { return "clang";}

◆ plugin_options()

const Options & casadi::PluginInterface< ImporterInternal >::plugin_options ( const std::string &  pname)
staticinherited

Definition at line 79 of file plugin_interface.hpp.

158  {
159  const Options *op = getPlugin(pname).options;
160  casadi_assert(op!=nullptr, "Plugin \"" + pname + "\" does not support options");
161  return *op;
162  }

◆ pluginFromRegFcn()

PluginInterface< ImporterInternal >::Plugin casadi::PluginInterface< ImporterInternal >::pluginFromRegFcn ( RegFcn  regfcn)
staticinherited

Definition at line 85 of file plugin_interface.hpp.

173  {
174  // Create a temporary struct
175  Plugin plugin;
176 
177  // Set the fields
178  int flag = regfcn(&plugin);
179  casadi_assert(flag==0, "Registration of plugin failed.");
180 
181  return plugin;
182  }

◆ read_external()

void casadi::ImporterInternal::read_external ( const std::string &  sym,
bool  inlined,
std::istream &  file,
casadi_int &  offset 
)
inherited

Definition at line 182 of file importer_internal.cpp.

183  {
184  // New entry
185  std::stringstream ss;
186 
187  // Are we still in the function declaration
188  bool in_declaration = true;
189 
190  // Loop over the lines
191  std::string line;
192  while (getline(file, line)) {
193  offset++;
194 
195  // Skip line if still in declaration
196  if (in_declaration) {
197  size_t stop = line.find('{');
198  if (stop != std::string::npos) in_declaration = false;
199  continue;
200  }
201 
202  // End of declaration found?
203  if (line.find("/*CASADIEXTERNAL") != std::string::npos) {
204  auto new_el = external_.insert(std::make_pair(sym, std::make_pair(inlined, ss.str())));
205  casadi_assert(new_el.second, "Duplicate symbol: \"" + sym + "\"");
206  return;
207  }
208 
209  // Add to entry
210  if (inlined) {
211  ss << line << std::endl;
212  }
213  }
214  casadi_error("End-of-file reached while searching for \"/*CASADIEXTERNAL\"");
215  }
bool inlined(const std::string &symname) const

References casadi::ImporterInternal::external_, and casadi::ImporterInternal::inlined().

Referenced by casadi::ImporterInternal::init().

◆ read_meta()

void casadi::ImporterInternal::read_meta ( std::istream &  file,
casadi_int &  offset 
)
inherited

Definition at line 135 of file importer_internal.cpp.

135  {
136  // Loop over the lines
137  std::string line;
138  while (getline(file, line)) {
139  offset++;
140 
141  // End of meta found?
142  if (line.find("*/") != std::string::npos) return;
143 
144  // If comment or empty line, skip
145  if (line.empty() || line.at(0)=='#') continue;
146 
147  // Get command string
148  casadi_assert(line.at(0)==':',
149  "Syntax error: " + line + " is not a command string");
150  std::string cmd = line.substr(1, line.find(' ')-1);
151 
152  // New entry
153  std::stringstream ss;
154 
155  // Collect the meta data
156  line = line.substr(cmd.size()+2);
157  while (true) {
158  // Find the backslash, if any
159  size_t stop = line.find('\\');
160 
161  // Add to entry
162  ss << line.substr(0, stop);
163 
164  // Break if not multiline
165  if (stop == std::string::npos) break;
166 
167  // Read another line
168  ss << std::endl;
169  if (!getline(file, line)) {
170  casadi_error("Failed to read \"" + cmd + "\"");
171  }
172  offset++;
173  }
174 
175  // Insert new element in map
176  auto new_el = meta_.insert(std::make_pair(cmd, std::make_pair(offset, ss.str())));
177  casadi_assert(new_el.second, "Duplicate entry: \"" + cmd + "\"");
178  }
179  casadi_error("End-of-file reached while searching for \"*/\"");
180  }

References casadi::ImporterInternal::meta_.

Referenced by casadi::ImporterInternal::init().

◆ registerPlugin() [1/2]

void casadi::PluginInterface< ImporterInternal >::registerPlugin ( const Plugin &  plugin,
bool  needs_lock = true 
)
staticinherited

Definition at line 96 of file plugin_interface.hpp.

278  {
279 
280 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
281  casadi::conditional_lock_guard<std::mutex> lock(Derived::mutex_solvers_, needs_lock);
282 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
283 
284  // Check if the solver name is in use
285  typename std::map<std::string, Plugin>::iterator it=Derived::solvers_.find(plugin.name);
286  casadi_assert(it==Derived::solvers_.end(),
287  "Solver " + str(plugin.name) + " is already in use");
288 
289  // Add to list of solvers
290  Derived::solvers_[plugin.name] = plugin;
291  }

◆ registerPlugin() [2/2]

void casadi::PluginInterface< ImporterInternal >::registerPlugin ( RegFcn  regfcn,
bool  needs_lock = true 
)
staticinherited

Definition at line 99 of file plugin_interface.hpp.

273  {
274  registerPlugin(pluginFromRegFcn(regfcn), needs_lock);
275  }

◆ serialize()

void casadi::ImporterInternal::serialize ( SerializingStream s) const
inherited

Definition at line 316 of file importer_internal.cpp.

316  {
317  serialize_type(s);
318  serialize_body(s);
319  }
virtual void serialize_body(SerializingStream &s) const
virtual void serialize_type(SerializingStream &s) const

References casadi::ImporterInternal::serialize_body(), and casadi::ImporterInternal::serialize_type().

◆ serialize_body()

void casadi::ImporterInternal::serialize_body ( SerializingStream s) const
virtualinherited

Definition at line 325 of file importer_internal.cpp.

325  {
326  s.version("ImporterInternal", 1);
327  s.pack("ImporterInternal::name", name_);
328  s.pack("ImporterInternal::meta", meta_);
329  s.pack("ImporterInternal::external", external_);
330  }

References casadi::ImporterInternal::external_, casadi::ImporterInternal::meta_, casadi::ImporterInternal::name_, casadi::SerializingStream::pack(), and casadi::SerializingStream::version().

Referenced by casadi::ImporterInternal::serialize().

◆ serialize_type()

void casadi::ImporterInternal::serialize_type ( SerializingStream s) const
virtualinherited

Definition at line 321 of file importer_internal.cpp.

321  {
322  s.pack("ImporterInternal::type", class_name());
323  }

References casadi::ImporterInternal::class_name(), and casadi::SerializingStream::pack().

Referenced by casadi::ImporterInternal::serialize().

◆ shared_from_this() [1/2]

B casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::shared_from_this ( )
inlineprotectedinherited

Definition at line 83 of file generic_shared_internal.hpp.

83  {
84  casadi_assert_dev(B::test_cast(static_cast<Internal*>(this)));
85  B ret;
86  ret.own(static_cast<Internal*>(this));
87  return ret;
88  }

◆ shared_from_this() [2/2]

const B casadi::GenericSharedInternal< SharedObject , SharedObjectInternal >::shared_from_this ( ) const
inlineprotectedinherited

Definition at line 92 of file generic_shared_internal.hpp.

92  {
93  casadi_assert_dev(B::test_cast(static_cast<const Internal*>(this)));
94  B ret;
95  ret.own(const_cast<Internal*>(static_cast<const Internal*>(this)));
96  return ret;
97  }

◆ shortname()

static std::string casadi::ImporterInternal::shortname ( )
inlinestaticinherited

Definition at line 104 of file importer_internal.hpp.

104 { return "importer";}

◆ to_text()

std::string casadi::ImporterInternal::to_text ( const std::string &  cmd,
casadi_int  ind = -1 
) const
inherited

◆ weak()

Extra doc: https://github.com/casadi/casadi/wiki/L_1ai

Definition at line 67 of file generic_shared_internal.hpp.

210  {
211 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
212  auto* w = weak_ref_.load(std::memory_order_acquire);
213  if (!w) {
214  auto* nw = new GenericWeakRef<Shared, Internal>(static_cast<Internal*>(this));
215  GenericWeakRef<Shared, Internal>* expected = nullptr;
216  if (weak_ref_.compare_exchange_strong(
217  expected, nw, std::memory_order_release, std::memory_order_acquire)) {
218  w = nw;
219  } else {
220  delete nw; // lost the race; another thread published first
221  w = expected;
222  }
223  }
224  return w;
225 #else
226  if (weak_ref_==nullptr) {
227  weak_ref_ = new GenericWeakRef<Shared, Internal>(static_cast<Internal*>(this));
228  }
229  return weak_ref_;
230 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
231  }

Member Data Documentation

◆ act_

clang::EmitLLVMOnlyAction* casadi::ClangCompiler::act_
protected

Definition at line 127 of file clang_compiler.hpp.

Referenced by ClangCompiler(), init(), and ~ClangCompiler().

◆ context_

llvm::LLVMContext* casadi::ClangCompiler::context_
protected

Definition at line 129 of file clang_compiler.hpp.

Referenced by ClangCompiler(), init(), and ~ClangCompiler().

◆ executionEngine_

llvm::ExecutionEngine* casadi::ClangCompiler::executionEngine_
protected

Definition at line 128 of file clang_compiler.hpp.

Referenced by ClangCompiler(), get_function(), init(), and ~ClangCompiler().

◆ external_

std::map<std::string, std::pair<bool, std::string> > casadi::ImporterInternal::external_
inherited

◆ flags_

std::vector<std::string> casadi::ClangCompiler::flags_

Definition at line 124 of file clang_compiler.hpp.

Referenced by init().

◆ include_path_

std::string casadi::ClangCompiler::include_path_

Definition at line 123 of file clang_compiler.hpp.

Referenced by init().

◆ infix_

const std::string casadi::ImporterInternal::infix_ = "importer"
staticinherited

Definition at line 101 of file importer_internal.hpp.

◆ meta_

std::map<std::string, std::pair<casadi_int, std::string> > casadi::ImporterInternal::meta_
inherited

◆ meta_doc

const std::string casadi::ClangCompiler::meta_doc
static
Initial value:
=
"\n"
"\n"
"\n"
"Interface to the JIT compiler CLANG\n"
"\n"
"Extra doc: https://github.com/casadi/casadi/wiki/L_21v \n"
"\n"
"\n"
">List of available options\n"
"\n"
"+--------------+-----------------+-----------------------------------------+\n"
"| Id | Type | Description |\n"
"+==============+=================+=========================================+\n"
"| flags | OT_STRINGVECTOR | Compile flags for the JIT compiler. |\n"
"| | | Default: None |\n"
"+--------------+-----------------+-----------------------------------------+\n"
"| include_path | OT_STRING | Include paths for the JIT compiler. The |\n"
"| | | include directory shipped with CasADi |\n"
"| | | will be automatically appended. |\n"
"+--------------+-----------------+-----------------------------------------+\n"
"\n"
"\n"
"\n"
"\n"

Definition at line 107 of file clang_compiler.hpp.

Referenced by casadi::casadi_register_importer_clang().

◆ module_

llvm::Module* casadi::ClangCompiler::module_
protected

Definition at line 131 of file clang_compiler.hpp.

Referenced by get_function(), and init().

◆ myerr_

llvm::raw_ostream* casadi::ClangCompiler::myerr_
protected

Definition at line 130 of file clang_compiler.hpp.

Referenced by ClangCompiler(), init(), and ~ClangCompiler().

◆ name_

std::string casadi::ImporterInternal::name_
inherited

◆ options_

const Options casadi::ClangCompiler::options_
static
Initial value:
{{"include_path",
"Include paths for the JIT compiler. "
"The include directory shipped with CasADi will be automatically appended."}},
{"flags",
"Compile flags for the JIT compiler. Default: None"}}
}
}
static const Options options_
Options.
@ OT_STRINGVECTOR

Definition at line 99 of file clang_compiler.hpp.

Referenced by casadi::casadi_register_importer_clang().

◆ solvers_

std::map< std::string, ImporterInternal::Plugin > casadi::ImporterInternal::solvers_
staticinherited

Definition at line 94 of file importer_internal.hpp.

◆ verbose_

bool casadi::ImporterInternal::verbose_
inherited

The documentation for this class was generated from the following files: