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_);