-
Notifications
You must be signed in to change notification settings - Fork 38
LibGeneration
Joao Rui Leal edited this page Feb 19, 2022
·
1 revision
There are some useful classes to automatically generate, compile and link a dynamic or static library in Linux.
Future version of CppADCodegen might also support this in other OSes, once the system abstraction functions are implemented.
Here is an example using GCC to compile a model library which is then linked and used in the same program.
#include <iosfwd>
#include <vector>
#include <cppad/cg.hpp>
using namespace CppAD;
using namespace CppAD::cg;
int main(void) {
// use a special object for source code generation
typedef CG<double> CGD;
typedef AD<CGD> ADCG;
/***************************************************************************
* the model
**************************************************************************/
// independent variable vector
std::vector<ADCG> x(2);
Independent(x);
// dependent variable vector
std::vector<ADCG> y(1);
// the model equation
ADCG a = x[0] / 1. + x[1] * x[1];
y[0] = a / 2;
ADFun<CGD> fun(x, y);
/***************************************************************************
* Create the dynamic library
* (generates and compiles source code)
**************************************************************************/
// generates source code
ModelCSourceGen<double> cgen(fun, "my_model");
cgen.setCreateJacobian(true);
cgen.setCreateForwardOne(true);
cgen.setCreateReverseOne(true);
cgen.setCreateReverseTwo(true);
ModelLibraryCSourceGen<double> libcgen(cgen);
// compile source code
DynamicModelLibraryProcessor<double> p(libcgen);
GccCompiler<double> compiler;
std::unique_ptr<DynamicLib<double>> dynamicLib = p.createDynamicLibrary(compiler);
// save to files (not really required)
SaveFilesModelLibraryProcessor<double> p2(libcgen);
p2.saveSources();
/***************************************************************************
* Use the dynamic library
**************************************************************************/
std::unique_ptr<GenericModel<double>> model = dynamicLib->model("my_model");
std::vector<double> xv {2.5, 3.5};
std::vector<double> jac = model->Jacobian(xv);
// print out the result
std::cout << jac[0] << " " << jac[1] << std::endl;
}
It should be noted that real world implementations would compile the model library only once and then reuse it whenever needed.
A good approach is to check if the library exists, and to only generate it whenever it is missing or outdated.