22 #include <cppad/core/to_csrc.hpp> 
   25 #include <benchmark/benchmark.h> 
   28   #define DLL_EXT ".dll" 
   43 typedef Eigen::Matrix<ADScalar, Eigen::Dynamic, 1> 
ADVectorXs;
 
   44 typedef Eigen::Matrix<ADCGScalar, Eigen::Dynamic, 1, Options> 
ADCGVectorXs;
 
   45 typedef Eigen::Matrix<ADScalar, Eigen::Dynamic, Eigen::Dynamic> 
ADMatrixXs;
 
   46 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> 
RowMatrixXs;
 
   74     const Eigen::VectorXd qmax(Eigen::VectorXd::Ones(
model.
nq));
 
   76     v = TangentVectorType::Random(
model.
nv);
 
   77     a = TangentVectorType::Random(
model.
nv);
 
   79     X = ConfigVectorType::Zero(
nx);
 
   89     ad_X = ADConfigVectorType::Zero(
nx);
 
  109   CppAD::jit_double 
toJIT(CppAD::ADFun<Scalar> & ad_fun, 
const std::string & suffix)
 
  112     std::string c_type = 
"double";
 
  113     std::string 
name = std::string(
"jit_JSIM_") + suffix;
 
  114     std::string csrc_file = std::string(
"./") + 
name + std::string(
".c");
 
  116     ofs.open(csrc_file, std::ofstream::out);
 
  117     ad_fun.to_csrc(ofs, c_type);
 
  121     std::string dll_file = std::string(
"./") + 
name + std::string(
DLL_EXT);
 
  122     CPPAD_TESTVECTOR(std::string) csrc_files(1);
 
  123     csrc_files[0] = csrc_file;
 
  124     std::map<std::string, std::string> options;
 
  125     std::string err_msg = CppAD::create_dll_lib(dll_file, csrc_files, options);
 
  128       std::cerr << 
name << 
": err_msg = " << err_msg << 
"\n";
 
  132     dll_linker = std::make_unique<CppAD::link_dll_lib>(dll_file, err_msg);
 
  135       std::cerr << 
name << 
": err_msg = " << err_msg << 
"\n";
 
  138     std::string function_name = std::string(
"cppad_jit_ad_fun_") + suffix;
 
  139     void * void_ptr = (*dll_linker)(function_name, err_msg);
 
  142       std::cerr << 
name << 
": err_msg = " << err_msg << 
"\n";
 
  145     return reinterpret_cast<CppAD::jit_double
>(void_ptr);
 
  148   std::unique_ptr<CppAD::cg::GenericModel<Scalar>>
 
  149   toBIN(
ADCGFun & ad_cg_fun, 
const std::string & suffix, 
bool create_jacobian = 
false)
 
  151     const std::string function_name = suffix;
 
  152     const std::string library_name = std::string(
"cg_") + suffix + std::string(
"_eval");
 
  153     const std::string compile_options = 
"-Ofast";
 
  156     CppAD::cg::ModelCSourceGen<Scalar> cgen(ad_cg_fun, function_name);
 
  157     cgen.setCreateForwardZero(
true);
 
  158     cgen.setCreateJacobian(create_jacobian);
 
  159     CppAD::cg::ModelLibraryCSourceGen<Scalar> libcgen(cgen);
 
  161     CppAD::cg::DynamicModelLibraryProcessor<Scalar> dynamicLibManager(libcgen, library_name);
 
  163     CppAD::cg::GccCompiler<Scalar> compiler(PINOCCHIO_CXX_COMPILER);
 
  164     std::vector<std::string> compile_flags = compiler.getCompileFlags();
 
  165     compile_flags[0] = compile_options;
 
  166     compiler.setCompileFlags(compile_flags);
 
  167     dynamicLibManager.createDynamicLibrary(compiler, 
false);
 
  169     const auto it = dynamicLibManager.getOptions().find(
"dlOpenMode");
 
  170     if (
it == dynamicLibManager.getOptions().end())
 
  172       dynamicLib_ptr = std::make_unique<CppAD::cg::LinuxDynamicLib<Scalar>>(
 
  173         dynamicLibManager.getLibraryName()
 
  174         + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION);
 
  178       int dlOpenMode = std::stoi(
it->second);
 
  179       dynamicLib_ptr = std::make_unique<CppAD::cg::LinuxDynamicLib<Scalar>>(
 
  180         dynamicLibManager.getLibraryName() + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION,
 
  219     std::cout << 
"nq = " << 
MODEL.
nq << std::endl;
 
  220     std::cout << 
"nv = " << 
MODEL.
nv << std::endl;
 
  221     std::cout << 
"name = " << 
MODEL.
name << std::endl;
 
  222     std::cout << 
"--" << std::endl;
 
  231   b->MinWarmUpTime(3.);
 
  240   data.M.triangularView<Eigen::StrictlyLower>() =
 
  241     data.M.transpose().triangularView<Eigen::StrictlyLower>();
 
  255   CppAD::ADFun<Scalar> & ad_fun,
 
  256   const CPPAD_TESTVECTOR(
Scalar) & x,
 
  257   CPPAD_TESTVECTOR(
Scalar) & M_vector)
 
  259   M_vector = ad_fun.Forward(0, 
x);
 
  263   CppAD::Independent(ad_q);
 
  265   ad_data.M.triangularView<Eigen::StrictlyLower>() =
 
  266     ad_data.M.transpose().triangularView<Eigen::StrictlyLower>();
 
  268     Eigen::Map<ADVectorXs>(ad_data.M.data(), ad_data.M.cols() * ad_data.M.rows());
 
  270   CppAD::ADFun<Scalar> ad_fun(ad_q, M_vector);
 
  271   ad_fun.function_name_set(
"ad_fun_crba");
 
  274   Eigen::Map<Data::ConfigVectorType>(
x.data(), 
model.nq, 1) = 
q;
 
  275   CPPAD_TESTVECTOR(
Scalar) res_M_vector;
 
  288   CppAD::Independent(ad_q);
 
  290   ad_data.M.triangularView<Eigen::StrictlyLower>() =
 
  291     ad_data.M.transpose().triangularView<Eigen::StrictlyLower>();
 
  293     Eigen::Map<ADVectorXs>(ad_data.M.data(), ad_data.M.cols() * ad_data.M.rows());
 
  295   CppAD::ADFun<Scalar> ad_fun(ad_q, M_vector);
 
  296   ad_fun.function_name_set(
"ad_fun_crba");
 
  299   Eigen::Map<Data::ConfigVectorType>(
x.data(), 
model.nq, 1) = 
q;
 
  300   size_t compare_change = 0, 
nx = (size_t)
model.nq, nM_vector = (
size_t)
model.nv * (size_t)
model.nv;
 
  301   CPPAD_TESTVECTOR(
Scalar) M_vector_jit(nM_vector);
 
  303   auto ad_fun_ptr = toJIT(ad_fun, 
"crba");
 
  306     ad_fun_ptr(
nx, 
x.data(), nM_vector, M_vector_jit.data(), &compare_change);
 
  315   CppAD::Independent(ad_cg_q);
 
  317   ad_cg_data.M.triangularView<Eigen::StrictlyLower>() =
 
  318     ad_cg_data.M.transpose().triangularView<Eigen::StrictlyLower>();
 
  321     Eigen::Map<ADCGVectorXs>(ad_cg_data.M.data(), ad_cg_data.M.cols() * ad_cg_data.M.rows());
 
  324   ad_cg_fun.Dependent(ad_cg_q, M_vector);
 
  325   ad_cg_fun.optimize(
"no_compare_op");
 
  329   Eigen::Map<Data::ConfigVectorType>(
x.data(), 
model.nq, 1) = 
q;
 
  331   auto generatedFun_ptr = toBIN(ad_cg_fun, 
"crba");
 
  335     generatedFun_ptr->ForwardZero(
x, 
y);
 
  345   const Eigen::VectorXd & q,
 
  346   const Eigen::VectorXd & 
v,
 
  347   const Eigen::VectorXd & 
a)
 
  363   CppAD::ADFun<Scalar> & ad_fun,
 
  364   const CPPAD_TESTVECTOR(
Scalar) & x,
 
  371   CppAD::Independent(ad_X);
 
  373     ad_model, ad_data, ad_X.segment(0, 
model.nq), ad_X.segment(
model.nq, 
model.nv),
 
  377   Eigen::Map<ADData::TangentVectorType>(ad_Y.data(), 
model.nv, 1) = ad_data.tau;
 
  379   CppAD::ADFun<Scalar> ad_fun(ad_X, ad_Y);
 
  383   Eigen::Map<Data::TangentVectorType>(
x.data(), 
nx, 1) = 
X;
 
  384   CPPAD_TESTVECTOR(
Scalar) res_dtau_da;
 
  397   CppAD::Independent(ad_X);
 
  399     ad_model, ad_data, ad_X.segment(0, 
model.nq), ad_X.segment(
model.nq, 
model.nv),
 
  403   Eigen::Map<ADData::TangentVectorType>(ad_Y.data(), 
model.nv, 1) = ad_data.tau;
 
  405   CppAD::ADFun<Scalar> 
f(ad_X, ad_Y);
 
  406   CppAD::ADFun<ADScalar, Scalar> af = 
f.base2ad();
 
  410   CppAD::Independent(ad_X);
 
  413   dtau_dx_vector = Eigen::Map<ADVectorXs>(dtau_dx.data(), dtau_dx.cols() * dtau_dx.rows());
 
  414   CppAD::ADFun<double> ad_fun(ad_X, dtau_dx_vector);
 
  415   ad_fun.function_name_set(
"ad_fun_rnea_derivatives");
 
  418   Eigen::Map<Data::TangentVectorType>(
x.data(), 
nx, 1) = 
X;
 
  419   size_t compare_change = 0, nx_ = (size_t)
nx, ndtau_dx = (
size_t)
model.nv * (size_t)
nx;
 
  420   std::vector<double> dtau_dx_jit(ndtau_dx);
 
  422   auto ad_fun_ptr = toJIT(ad_fun, 
"rnea_derivatives");
 
  425     ad_fun_ptr(nx_, 
x.data(), ndtau_dx, dtau_dx_jit.data(), &compare_change);
 
  438   CppAD::Independent(ad_cg_X);
 
  440     ad_cg_model, ad_cg_data, ad_cg_X.segment(0, 
model.nq), ad_cg_X.segment(
model.nq, 
model.nv),
 
  443   Eigen::Map<ADCGData::TangentVectorType>(ad_cg_Y.data(), 
model.nv, 1) = ad_cg_data.tau;
 
  444   ad_cg_fun.Dependent(ad_cg_X, ad_cg_Y);
 
  445   ad_cg_fun.optimize(
"no_compare_op");
 
  447   RowMatrixXs jac = RowMatrixXs::Zero(ad_cg_Y.size(), ad_cg_X.size());
 
  449   Eigen::Map<Data::TangentVectorType>(
x.data(), 
nx, 1) = 
X;
 
  451   auto generatedFun_ptr = toBIN(ad_cg_fun, 
"crba_derivatives", 
true);
 
  452   CppAD::cg::ArrayView<Scalar> jac_(
jac.data(), (
size_t)
jac.size());
 
  456     generatedFun_ptr->Jacobian(
x, jac_);