roadrunner  2.6.0
Fast simulator for SBML models
Jit.h
1 //
2 // Created by Ciaran on 25/10/2021.
3 //
4 
5 #ifndef ROADRUNNER_JIT_H
6 #define ROADRUNNER_JIT_H
7 
8 #define NOMINMAX
9 
10 #include <rrSparse.h>
11 #include "LLVMException.h"
12 #include "rrSparse.h"
13 #include <unordered_map>
14 
15 #ifdef _MSC_VER
16 #pragma warning(disable: 4146)
17 #pragma warning(disable: 4141)
18 #pragma warning(disable: 4267)
19 #pragma warning(disable: 4624)
20 #endif
21 
22 #include <llvm/Analysis/TargetLibraryInfo.h>
23 #include "llvm/IR/IRBuilder.h"
24 #include "llvm/ExecutionEngine/ObjectCache.h"
25 #include "llvm/Target/TargetMachine.h"
26 #include "llvm/Object/ObjectFile.h"
27 #include "llvm/IR/Mangler.h"
28 
29 #ifdef _MSC_VER
30 #pragma warning(default: 4146)
31 #pragma warning(default: 4141)
32 #pragma warning(default: 4267)
33 #pragma warning(default: 4624)
34 #endif
35 
36 namespace rr {
37  class ExecutableModel;
38 
39 }
40 
41 namespace rrllvm {
42  class Random;
43 
44  class ModelResources;
45 
46  class SBMLModelObjectCache;
47 
48  template<typename FunctionPtrType>
49  class CodeGenBase;
50 
51 
56  using FnPtr_d1 = double (*)(double x);
57  using FnPtr_i1 = int (*)(int x);
58  using FnPtr_d2 = double (*)(double x, double y);
59 
60  // these are taken from C library by createCLibraryFunctions
61  using fabsFnTy = FnPtr_d1;
62  using acosFnTy = FnPtr_d1;
63  using asinFnTy = FnPtr_d1;
64  using atanFnTy = FnPtr_d1;
65  using ceilFnTy = FnPtr_d1;
66  using cosFnTy = FnPtr_d1;
67  using coshFnTy = FnPtr_d1;
68  using expFnTy = FnPtr_d1;
69  using floorFnTy = FnPtr_d1;
70  using logFnTy = FnPtr_d1;
71  using log10FnTy = FnPtr_d1;
72  using sinFnTy = FnPtr_d1;
73  using sinhFnTy = FnPtr_d1;
74  using tanFnTy = FnPtr_d1;
75  using tanhFnTy = FnPtr_d1;
76  using fmodFnTy = FnPtr_d2;
77  using powFnTy = FnPtr_d2;
78 
79  // these are defined locally by roadrunner in SBMLSupportFunctions
80  using arccotFnTy = FnPtr_d1;
81  using rr_arccot_negzeroFnTy = FnPtr_d1;
82  using arccothFnTy = FnPtr_d1;
83  using arccscFnTy = FnPtr_d1;
84  using arccschFnTy = FnPtr_d1;
85  using arcsecFnTy = FnPtr_d1;
86  using arcsechFnTy = FnPtr_d1;
87  using cotFnTy = FnPtr_d1;
88  using cothFnTy = FnPtr_d1;
89  using cscFnTy = FnPtr_d1;
90  using cschFnTy = FnPtr_d1;
91  using secFnTy = FnPtr_d1;
92  using sechFnTy = FnPtr_d1;
93  using arccoshFnTy = FnPtr_d1;
94  using arcsinhFnTy = FnPtr_d1;
95  using arctanhFnTy = FnPtr_d1;
96  using rr_factorialdFnTy = FnPtr_d1;
97  using rr_factorialiFnTy = FnPtr_i1;
98  using rr_logdFnTy = FnPtr_d2;
99  using rr_rootdFnTy = FnPtr_d2;
100  using quotientFnTy = FnPtr_d2;
101  using rr_maxFnTy = FnPtr_d2;
102  using rr_minFnTy = FnPtr_d2;
103 
104  // for a sparse matrix used in llvm world
105  using csr_matrix_set_nz_FnTy = rr::csr_matrix *(*)(int, int, double);
106  using csr_matrix_get_nz_FnTy = rr::csr_matrix *(*)(int, int);
107 
108  // function signatures for distrib
109  using DistribFnTy_d1 = double (*)(Random *, double);
110  using DistribFnTy_d2 = double (*)(Random *, double, double);
111  using DistribFnTy_d3 = double (*)(Random *, double, double, double);
112  using DistribFnTy_d4 = double (*)(Random *, double, double, double, double);
113 
114  using distrib_bernoulli_FnTy = DistribFnTy_d1;
115  using distrib_cauchy_one_FnTy = DistribFnTy_d1;
116  using distrib_chisquare_FnTy = DistribFnTy_d1;
117  using distrib_exponential_FnTy = DistribFnTy_d1;
118  using distrib_laplace_one_FnTy = DistribFnTy_d1;
119  using distrib_poisson_FnTy = DistribFnTy_d1;
120  using distrib_rayleigh_FnTy = DistribFnTy_d1;
121  using distrib_uniform_FnTy = DistribFnTy_d2;
122  using distrib_normal_FnTy = DistribFnTy_d2;
123  using distrib_binomial_FnTy = DistribFnTy_d2;
124  using distrib_cauchy_FnTy = DistribFnTy_d2;
125  using distrib_gamma_FnTy = DistribFnTy_d2;
126  using distrib_laplace_FnTy = DistribFnTy_d2;
127  using distrib_lognormal_FnTy = DistribFnTy_d2;
128  using distrib_chisquare_three_FnTy = DistribFnTy_d3;
129  using distrib_exponential_three_FnTy = DistribFnTy_d3;
130  using distrib_poisson_three_FnTy = DistribFnTy_d3;
131  using distrib_rayleigh_three_FnTy = DistribFnTy_d3;
132  using distrib_normal_four_FnTy = DistribFnTy_d4;
133  using distrib_binomial_four_FnTy = DistribFnTy_d4;
134  using distrib_cauchy_four_FnTy = DistribFnTy_d4;
135  using distrib_gamma_four_FnTy = DistribFnTy_d4;
136  using distrib_laplace_four_FnTy = DistribFnTy_d4;
137  using distrib_lognormal_four_FnTy = DistribFnTy_d4;
138 
139  using rrOwningBinary = llvm::object::OwningBinary<llvm::object::ObjectFile>;
140 
144  using FnMap = std::unordered_map<std::string, std::pair<llvm::FunctionType *, void *>>;
145 
150  class Jit {
151  public:
152 
159  explicit Jit(std::uint32_t options);
160 
167  Jit();
168 
175  virtual void mapFunctionsToJitSymbols() = 0;
176 
184 // virtual void mapDistribFunctionsToJitSymbols() = 0;
185 
189  virtual ~Jit() = default;
190 
213  virtual std::uint64_t lookupFunctionAddress(const std::string &name) = 0;
214 
220  virtual void addObjectFile(rrOwningBinary owningObject) = 0;
221 
225  virtual void addObjectFile(std::unique_ptr<llvm::object::ObjectFile> objectFile) = 0;
226 
230  virtual void addObjectFile(std::unique_ptr<llvm::MemoryBuffer> obj) = 0;
231 
235  virtual void addModule(llvm::Module *M) = 0;
236 
244  virtual void addModule(std::unique_ptr<llvm::Module> M, std::unique_ptr<llvm::LLVMContext> ctx) = 0;
245 
253  virtual void addModule() = 0;
254 
258  virtual const llvm::DataLayout &getDataLayout() const = 0;
259 
266  virtual std::unique_ptr<llvm::MemoryBuffer> getCompiledModelFromCache(const std::string &sbmlMD5) = 0;
267 
271  virtual void transferObjectsToResources(std::shared_ptr<rrllvm::ModelResources> modelResources);
272 
281  virtual void mapLLVMGeneratedFunctionsToSymbols(ModelResources *modelResources, std::uint32_t options);
282 
286  virtual llvm::Module *getModuleNonOwning();
287 
291  virtual llvm::LLVMContext *getContextNonOwning();
292 
296  virtual llvm::IRBuilder<> *getBuilderNonOwning();
297 
302  virtual std::string emitToString();
303 
307  llvm::raw_svector_ostream &getCompiledModuleStream();
308 
309  std::string getDefaultTargetTriple() const;
310 
311  void setModuleIdentifier(const std::string &id);
312 
313  virtual std::string mangleName(const std::string &unmangledName) const;
314 
329  virtual std::string getModuleAsString(std::string sbmlMD5) = 0;
330 
339  std::unique_ptr<llvm::raw_svector_ostream> compiledModuleBinaryStream;
340 
344  llvm::SmallVector<char, 10> moduleBuffer;
345  protected:
346 
350  std::string getProcessTriple() const;
351 
356  const llvm::Target *getDefaultTargetMachine() const;
357 
361  FnMap externalFunctionSignatures() const;
362 
363 
364  std::unique_ptr<llvm::LLVMContext> context;
365  std::unique_ptr<llvm::Module> module;
366  llvm::Module *moduleNonOwning = nullptr;
367  std::unique_ptr<llvm::IRBuilder<>> builder;
368  std::uint32_t options;
369 
370 
371  private:
372 
373 
388  void createCLibraryFunction(llvm::LibFunc funcId, llvm::FunctionType *funcType);
389 
399  void createCLibraryFunctions();
400 
401 
402  };
403 }
404 
405 #endif //ROADRUNNER_JIT_H
superclass of all Jit types.
Definition: Jit.h:150
virtual void addObjectFile(std::unique_ptr< llvm::object::ObjectFile > objectFile)=0
add an in-memory representation of an object file to the current jit module.
virtual void mapLLVMGeneratedFunctionsToSymbols(ModelResources *modelResources, std::uint32_t options)
Map the Jit'd functions that collectively represent a roadrunner compiled sbml model to symbols in th...
Definition: Jit.cpp:101
llvm::SmallVector< char, 10 > moduleBuffer
The buffer used by compiledModuleBinaryStream.
Definition: Jit.h:344
virtual void addObjectFile(rrOwningBinary owningObject)=0
add an in-memory representation of an object file to the current jit module.
virtual llvm::LLVMContext * getContextNonOwning()
returns a non owning pointer to the llvm::LLVMContext instance
Definition: Jit.cpp:76
llvm::raw_svector_ostream & getCompiledModuleStream()
get the stream that stores a compiled module as binary.
virtual void addObjectFile(std::unique_ptr< llvm::MemoryBuffer > obj)=0
add an in-memory representation of an object file to the current jit module.
virtual ~Jit()=default
Add support for libsbml distrib functions.
virtual std::string getModuleAsString(std::string sbmlMD5)=0
get a binary string representation of the current module.
virtual void mapFunctionsToJitSymbols()=0
adds functions that are declared and defined in C++ to the jit engine.
std::string getProcessTriple() const
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Jit.cpp:314
virtual llvm::Module * getModuleNonOwning()
returns a non owning pointer to the llvm::Module instance
Definition: Jit.cpp:72
FnMap externalFunctionSignatures() const
returns a mapping between function names and function signatures
Definition: Jit.cpp:337
std::unique_ptr< llvm::raw_svector_ostream > compiledModuleBinaryStream
MCJit compiles the generated LLVM IR to this binary stream which is then used both for adding to the ...
Definition: Jit.h:339
virtual const llvm::DataLayout & getDataLayout() const =0
get the DataLayout currently in use in the Jit
virtual std::string emitToString()
Write the Jit::module in its current state to string as LLVM IR.
Definition: Jit.cpp:207
virtual void transferObjectsToResources(std::shared_ptr< rrllvm::ModelResources > modelResources)
Moves objects over to ModelResources ptr
Definition: Jit.cpp:95
virtual std::unique_ptr< llvm::MemoryBuffer > getCompiledModelFromCache(const std::string &sbmlMD5)=0
lookup the sbml with the md5
Jit()
default constructor.
Definition: Jit.cpp:69
virtual void addModule(llvm::Module *M)=0
add a module
virtual void addModule(std::unique_ptr< llvm::Module > M, std::unique_ptr< llvm::LLVMContext > ctx)=0
add a module
const llvm::Target * getDefaultTargetMachine() const
use llvm calls to work out which TargetMachine is currently being used.
Definition: Jit.cpp:323
virtual void addModule()=0
add the module and context which are member variables of the Jit instance to the current Jit engine.
virtual llvm::IRBuilder * getBuilderNonOwning()
returns a non owning pointer to the llvm::LLVMContext instance
Definition: Jit.cpp:91