22 #define DLL_EXT ".dll"
33 using namespace Eigen;
38 const int NBT = 1000 * 100;
41 std::cout <<
"(the time score in debug mode is not relevant) " << std::endl;
45 using CppAD::NearEqual;
52 typedef AD<Scalar> ADScalar;
53 typedef CppAD::cg::CG<Scalar> CGScalar;
54 typedef CppAD::AD<CGScalar> ADCGScalar;
55 typedef CppAD::ADFun<CGScalar> ADCGFun;
57 typedef Eigen::Matrix<ADScalar, Eigen::Dynamic, 1> ADVectorXs;
58 typedef Eigen::Matrix<ADCGScalar, Eigen::Dynamic, 1, Options> ADCGVectorXs;
59 typedef Eigen::Matrix<ADScalar, Eigen::Dynamic, Eigen::Dynamic> ADMatrixXs;
60 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
RowMatrixXs;
74 typedef ADModel::ConfigVectorType ADConfigVectorType;
75 typedef ADModel::TangentVectorType ADTangentVectorType;
77 typedef ADCGModel::ConfigVectorType ADCGConfigVectorType;
78 typedef ADCGModel::TangentVectorType ADCGTangentVectorType;
85 model.lowerPositionLimit.head<3>().
fill(-1.);
86 model.upperPositionLimit.head<3>().
fill(1.);
88 ConfigVectorType
q(
nq);
90 TangentVectorType
v(TangentVectorType::Random(
nv));
91 TangentVectorType
a(TangentVectorType::Random(
nv));
96 std::vector<ConfigVectorType>
qs;
97 for (
size_t it = 0;
it < NBT; ++
it)
107 data.M.triangularView<Eigen::StrictlyLower>() =
108 data.M.transpose().triangularView<Eigen::StrictlyLower>();
110 std::cout <<
"Calculate data.M (JSIM) with CRBA =\t\t";
111 timer.
toc(std::cout, NBT);
115 ADModel ad_model =
model.cast<ADScalar>();
116 ADData ad_data(ad_model);
118 ADConfigVectorType ad_q =
q.cast<ADScalar>();
120 CppAD::Independent(ad_q);
122 ad_data.M.triangularView<Eigen::StrictlyLower>() =
123 ad_data.M.transpose().triangularView<Eigen::StrictlyLower>();
125 ADVectorXs M_vector =
126 Eigen::Map<ADVectorXs>(ad_data.M.data(), ad_data.M.cols() * ad_data.M.rows());
128 CppAD::ADFun<Scalar> ad_fun(ad_q, M_vector);
129 ad_fun.function_name_set(
"ad_fun_crba");
132 std::vector<CPPAD_TESTVECTOR(
Scalar)> xs;
133 for (
size_t it = 0;
it < NBT; ++
it)
136 Eigen::Map<Data::ConfigVectorType>(
x.data(),
nq, 1) =
q;
143 CPPAD_TESTVECTOR(
Scalar) M_vector = ad_fun.Forward(0, xs[_smooth]);
145 std::cout <<
"Calculate data.M (JSIM) using CppAD =\t\t";
146 timer.
toc(std::cout, NBT);
150 ADModel ad_model =
model.cast<ADScalar>();
151 ADData ad_data(ad_model);
153 ADConfigVectorType ad_q =
q.cast<ADScalar>();
155 CppAD::Independent(ad_q);
157 ad_data.M.triangularView<Eigen::StrictlyLower>() =
158 ad_data.M.transpose().triangularView<Eigen::StrictlyLower>();
160 ADVectorXs M_vector =
161 Eigen::Map<ADVectorXs>(ad_data.M.data(), ad_data.M.cols() * ad_data.M.rows());
163 CppAD::ADFun<Scalar> ad_fun(ad_q, M_vector);
164 ad_fun.function_name_set(
"ad_fun_crba");
167 std::string c_type =
"double";
168 std::string csrc_file =
"./jit_JSIM_crba.c";
170 ofs.open(csrc_file, std::ofstream::out);
171 ad_fun.to_csrc(ofs, c_type);
175 std::string dll_file =
"./jit_JSIM_crba" DLL_EXT;
176 CPPAD_TESTVECTOR(std::string) csrc_files(1);
177 csrc_files[0] = csrc_file;
178 std::map<std::string, std::string> options;
179 std::string err_msg = CppAD::create_dll_lib(dll_file, csrc_files, options);
182 std::cerr <<
"jit_JSIM_crba: err_msg = " << err_msg <<
"\n";
186 CppAD::link_dll_lib dll_linker(dll_file, err_msg);
189 std::cerr <<
"jit_JSIM_crba: err_msg = " << err_msg <<
"\n";
192 std::string function_name =
"cppad_jit_ad_fun_crba";
193 void * void_ptr = dll_linker(function_name, err_msg);
196 std::cerr <<
"jit_JSIM_crba: err_msg = " << err_msg <<
"\n";
199 using CppAD::jit_double;
200 jit_double ad_fun_ptr =
reinterpret_cast<jit_double
>(void_ptr);
203 size_t compare_change = 0,
nx = (size_t)
nq, nM_vector = (
size_t)
nv * (size_t)
nv;
204 CPPAD_TESTVECTOR(
Scalar) M_vector_jit(nM_vector);
206 std::vector<CPPAD_TESTVECTOR(
Scalar)> xs;
207 for (
size_t it = 0;
it < NBT; ++
it)
210 Eigen::Map<Data::ConfigVectorType>(
x.data(),
nq, 1) =
q;
217 ad_fun_ptr(
nx, xs[_smooth].
data(), nM_vector, M_vector_jit.data(), &compare_change);
219 std::cout <<
"Calculate data.M (JSIM) using CppAD-jit =\t";
220 timer.
toc(std::cout, NBT);
224 ADCGModel ad_model(
model.template cast<ADCGScalar>());
225 ADCGData ad_data(ad_model);
227 ADCGConfigVectorType ad_q =
q.cast<ADCGScalar>();
228 ad_q =
q.cast<ADCGScalar>();
230 std::unique_ptr<CppAD::cg::ModelCSourceGen<Scalar>> cgen_ptr;
231 std::unique_ptr<CppAD::cg::ModelLibraryCSourceGen<Scalar>> libcgen_ptr;
232 std::unique_ptr<CppAD::cg::DynamicModelLibraryProcessor<Scalar>> dynamicLibManager_ptr;
233 std::unique_ptr<CppAD::cg::DynamicLib<Scalar>> dynamicLib_ptr;
234 std::unique_ptr<CppAD::cg::GenericModel<Scalar>> generatedFun_ptr;
236 const std::string & function_name =
"crba";
237 const std::string & library_name =
"cg_crba_eval";
238 const std::string & compile_options =
"-Ofast";
240 CppAD::Independent(ad_q);
242 ad_data.M.triangularView<Eigen::StrictlyLower>() =
243 ad_data.M.transpose().triangularView<Eigen::StrictlyLower>();
245 ADCGVectorXs M_vector =
246 Eigen::Map<ADCGVectorXs>(ad_data.M.data(), ad_data.M.cols() * ad_data.M.rows());
249 ad_fun.Dependent(ad_q, M_vector);
250 ad_fun.optimize(
"no_compare_op");
253 cgen_ptr = std::unique_ptr<CppAD::cg::ModelCSourceGen<Scalar>>(
254 new CppAD::cg::ModelCSourceGen<Scalar>(ad_fun, function_name));
255 cgen_ptr->setCreateForwardZero(
true);
256 cgen_ptr->setCreateJacobian(
false);
257 libcgen_ptr = std::unique_ptr<CppAD::cg::ModelLibraryCSourceGen<Scalar>>(
258 new CppAD::cg::ModelLibraryCSourceGen<Scalar>(*cgen_ptr));
260 dynamicLibManager_ptr = std::unique_ptr<CppAD::cg::DynamicModelLibraryProcessor<Scalar>>(
261 new CppAD::cg::DynamicModelLibraryProcessor<Scalar>(*libcgen_ptr, library_name));
263 CppAD::cg::GccCompiler<Scalar> compiler(PINOCCHIO_CXX_COMPILER);
264 std::vector<std::string> compile_flags = compiler.getCompileFlags();
265 compile_flags[0] = compile_options;
266 compiler.setCompileFlags(compile_flags);
267 dynamicLibManager_ptr->createDynamicLibrary(compiler,
false);
269 const auto it = dynamicLibManager_ptr->getOptions().find(
"dlOpenMode");
270 if (
it == dynamicLibManager_ptr->getOptions().end())
272 dynamicLib_ptr.reset(
new CppAD::cg::LinuxDynamicLib<Scalar>(
273 dynamicLibManager_ptr->getLibraryName()
274 + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION));
278 int dlOpenMode = std::stoi(
it->second);
279 dynamicLib_ptr.reset(
new CppAD::cg::LinuxDynamicLib<Scalar>(
280 dynamicLibManager_ptr->getLibraryName()
281 + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION,
285 generatedFun_ptr = dynamicLib_ptr->model(function_name.c_str());
288 CPPAD_TESTVECTOR(
Scalar)
y((
size_t)
nv * (
size_t)
nv);
290 std::vector<CPPAD_TESTVECTOR(
Scalar)> xs;
291 for (
size_t it = 0;
it < NBT; ++
it)
294 Eigen::Map<Data::ConfigVectorType>(
x.data(),
nq, 1) =
q;
301 generatedFun_ptr->ForwardZero(xs[_smooth],
y);
303 std::cout <<
"Calculate data.M (JSIM) using CppADCodeGen =\t";
304 timer.
toc(std::cout, NBT);
307 std::cout << std::endl;
312 std::vector<ConfigVectorType>
qs, vs, as;
313 for (
size_t it = 0;
it < NBT; ++
it)
316 TangentVectorType
v(TangentVectorType::Random(
nv));
317 TangentVectorType
a(TangentVectorType::Random(
nv));
328 std::cout <<
"Calculate dtau_dx with computeRNEADerivatives =\t";
329 timer.
toc(std::cout, NBT);
333 ADModel ad_model =
model.cast<ADScalar>();
334 ADData ad_data(ad_model);
336 ADConfigVectorType ad_q =
q.cast<ADScalar>();
337 ADTangentVectorType ad_v =
v.cast<ADScalar>();
338 ADTangentVectorType ad_a =
a.cast<ADScalar>();
340 ADConfigVectorType ad_X = ADConfigVectorType::Zero(
nq + 2 *
nv);
341 Eigen::DenseIndex
i = 0;
342 ad_X.segment(
i,
nq) = ad_q;
344 ad_X.segment(
i,
nv) = ad_v;
346 ad_X.segment(
i,
nv) = ad_a;
349 CppAD::Independent(ad_X);
351 ad_model, ad_data, ad_X.segment(0,
nq), ad_X.segment(
nq,
nv), ad_X.segment(
nq +
nv,
nv));
354 Eigen::Map<ADData::TangentVectorType>(ad_Y.data(),
nv, 1) = ad_data.tau;
356 CppAD::ADFun<Scalar> ad_fun(ad_X, ad_Y);
359 std::vector<CPPAD_TESTVECTOR(
Scalar)> xs;
360 for (
size_t it = 0;
it < NBT; ++
it)
363 TangentVectorType
v(TangentVectorType::Random(
nv));
364 TangentVectorType
a(TangentVectorType::Random(
nv));
365 ConfigVectorType _x = ConfigVectorType::Zero(
nq + 2 *
nv);
366 Eigen::DenseIndex
i = 0;
367 _x.segment(
i,
nq) =
q;
369 _x.segment(
i,
nv) =
v;
371 _x.segment(
i,
nv) =
a;
374 Eigen::Map<Data::TangentVectorType>(
x.data(),
nx, 1) = _x;
380 CPPAD_TESTVECTOR(
Scalar)
dtau_da = ad_fun.Jacobian(xs[_smooth]);
382 std::cout <<
"Calculate dtau_dx (∂RNEA) using CppAD =\t\t";
383 timer.
toc(std::cout, NBT);
387 ADModel ad_model =
model.cast<ADScalar>();
388 ADData ad_data(ad_model);
390 ADConfigVectorType ad_q =
q.cast<ADScalar>();
391 ADTangentVectorType ad_v =
v.cast<ADScalar>();
392 ADTangentVectorType ad_a =
a.cast<ADScalar>();
393 ADConfigVectorType ad_X = ADConfigVectorType::Zero(
nx);
394 Eigen::DenseIndex
i = 0;
395 ad_X.segment(
i,
nq) = ad_q;
397 ad_X.segment(
i,
nv) = ad_v;
399 ad_X.segment(
i,
nv) = ad_a;
402 CppAD::Independent(ad_X);
404 ad_model, ad_data, ad_X.segment(0,
nq), ad_X.segment(
nq,
nv), ad_X.segment(
nq +
nv,
nv));
407 Eigen::Map<ADData::TangentVectorType>(ad_Y.data(),
nv, 1) = ad_data.tau;
409 CppAD::ADFun<Scalar>
f(ad_X, ad_Y);
410 CppAD::ADFun<ADScalar, Scalar> af =
f.base2ad();
412 CppAD::Independent(ad_X);
413 ADMatrixXs dtau_dx = af.Jacobian(ad_X);
414 ADVectorXs dtau_dx_vector(
nv *
nx);
415 dtau_dx_vector = Eigen::Map<ADVectorXs>(dtau_dx.data(), dtau_dx.cols() * dtau_dx.rows());
416 CppAD::ADFun<double> ad_fun(ad_X, dtau_dx_vector);
418 ad_fun.function_name_set(
"ad_fun");
421 std::string c_type =
"double";
422 std::string csrc_file =
"./jit_JSIM.c";
424 ofs.open(csrc_file, std::ofstream::out);
425 ad_fun.to_csrc(ofs, c_type);
429 std::string dll_file =
"./jit_JSIM" DLL_EXT;
430 CPPAD_TESTVECTOR(std::string) csrc_files(1);
431 csrc_files[0] = csrc_file;
432 std::map<std::string, std::string> options;
433 std::string err_msg = CppAD::create_dll_lib(dll_file, csrc_files, options);
436 std::cerr <<
"jit_JSIM: err_msg = " << err_msg <<
"\n";
440 CppAD::link_dll_lib dll_linker(dll_file, err_msg);
443 std::cerr <<
"jit_JSIM: err_msg = " << err_msg <<
"\n";
446 std::string function_name =
"cppad_jit_ad_fun";
447 void * void_ptr = dll_linker(function_name, err_msg);
450 std::cerr <<
"jit_JSIM: err_msg = " << err_msg <<
"\n";
453 using CppAD::jit_double;
454 jit_double ad_fun_ptr =
reinterpret_cast<jit_double
>(void_ptr);
457 std::vector<CPPAD_TESTVECTOR(
Scalar)> xs;
458 for (
size_t it = 0;
it < NBT; ++
it)
461 TangentVectorType
v(TangentVectorType::Random(
nv));
462 TangentVectorType
a(TangentVectorType::Random(
nv));
463 ConfigVectorType _x = ConfigVectorType::Zero(
nx);
464 Eigen::DenseIndex
i = 0;
465 _x.segment(
i,
nq) =
q;
467 _x.segment(
i,
nv) =
v;
469 _x.segment(
i,
nv) =
a;
472 Eigen::Map<Data::TangentVectorType>(
x.data(),
nx, 1) = _x;
476 size_t compare_change = 0, nx_ = (size_t)
nx, ndtau_dx = (
size_t)
nv * (size_t)
nx;
477 std::vector<double> dtau_dx_jit(ndtau_dx);
482 ad_fun_ptr(nx_, xs[_smooth].
data(), ndtau_dx, dtau_dx_jit.data(), &compare_change);
484 std::cout <<
"Calculate dtau_dx (∂RNEA) using CppAD-jit =\t";
485 timer.
toc(std::cout, NBT);
489 ADCGModel ad_model(
model.template cast<ADCGScalar>());
490 ADCGData ad_data(ad_model);
492 ADCGVectorXs ad_Y(
nv);
494 ADCGConfigVectorType ad_q =
q.cast<ADCGScalar>();
495 ADCGTangentVectorType ad_v =
v.cast<ADCGScalar>();
496 ADCGTangentVectorType ad_a =
a.cast<ADCGScalar>();
497 ADCGConfigVectorType ad_X = ADCGConfigVectorType::Zero(
nx);
498 Eigen::DenseIndex
i = 0;
499 ad_X.segment(
i,
nq) = ad_q;
501 ad_X.segment(
i,
nv) = ad_v;
503 ad_X.segment(
i,
nv) = ad_a;
508 std::unique_ptr<CppAD::cg::ModelCSourceGen<Scalar>> cgen_ptr;
509 std::unique_ptr<CppAD::cg::ModelLibraryCSourceGen<Scalar>> libcgen_ptr;
510 std::unique_ptr<CppAD::cg::DynamicModelLibraryProcessor<Scalar>> dynamicLibManager_ptr;
511 std::unique_ptr<CppAD::cg::DynamicLib<Scalar>> dynamicLib_ptr;
512 std::unique_ptr<CppAD::cg::GenericModel<Scalar>> generatedFun_ptr;
514 const std::string & function_name =
"rnea";
515 const std::string & library_name =
"cg_rnea_eval";
516 const std::string & compile_options =
"-Ofast";
518 CppAD::Independent(ad_X);
520 ad_model, ad_data, ad_X.segment(0,
nq), ad_X.segment(
nq,
nv), ad_X.segment(
nq +
nv,
nv));
522 ad_fun.Dependent(ad_X, ad_Y);
523 ad_fun.optimize(
"no_compare_op");
527 cgen_ptr = std::unique_ptr<CppAD::cg::ModelCSourceGen<Scalar>>(
528 new CppAD::cg::ModelCSourceGen<Scalar>(ad_fun, function_name));
529 cgen_ptr->setCreateForwardZero(
true);
530 cgen_ptr->setCreateJacobian(
true);
531 libcgen_ptr = std::unique_ptr<CppAD::cg::ModelLibraryCSourceGen<Scalar>>(
532 new CppAD::cg::ModelLibraryCSourceGen<Scalar>(*cgen_ptr));
534 dynamicLibManager_ptr = std::unique_ptr<CppAD::cg::DynamicModelLibraryProcessor<Scalar>>(
535 new CppAD::cg::DynamicModelLibraryProcessor<Scalar>(*libcgen_ptr, library_name));
537 CppAD::cg::GccCompiler<Scalar> compiler(PINOCCHIO_CXX_COMPILER);
538 std::vector<std::string> compile_flags = compiler.getCompileFlags();
539 compile_flags[0] = compile_options;
540 compiler.setCompileFlags(compile_flags);
541 dynamicLibManager_ptr->createDynamicLibrary(compiler,
false);
543 const auto it = dynamicLibManager_ptr->getOptions().find(
"dlOpenMode");
544 if (
it == dynamicLibManager_ptr->getOptions().end())
546 dynamicLib_ptr.reset(
new CppAD::cg::LinuxDynamicLib<Scalar>(
547 dynamicLibManager_ptr->getLibraryName()
548 + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION));
552 int dlOpenMode = std::stoi(
it->second);
553 dynamicLib_ptr.reset(
new CppAD::cg::LinuxDynamicLib<Scalar>(
554 dynamicLibManager_ptr->getLibraryName()
555 + CppAD::cg::system::SystemInfo<>::DYNAMIC_LIB_EXTENSION,
559 generatedFun_ptr = dynamicLib_ptr->model(function_name.c_str());
562 std::vector<size_t> xs;
563 for (
size_t it = 0;
it < NBT; ++
it)
566 TangentVectorType
v(TangentVectorType::Random(
nv));
567 TangentVectorType
a(TangentVectorType::Random(
nv));
569 ConfigVectorType
x = ConfigVectorType::Zero(
nq + 2 *
nv);
571 x.segment(
i,
nq) =
q;
573 x.segment(
i,
nv) =
v;
575 x.segment(
i,
nv) =
a;
578 xs.push_back(
static_cast<size_t>(
x.size()));
581 CppAD::cg::ArrayView<Scalar> jac_(
jac.data(), (
size_t)
jac.size());
586 generatedFun_ptr->Jacobian(CppAD::cg::ArrayView<const Scalar>(
x.data(), xs[_smooth]), jac_);
588 std::cout <<
"Calculate dtau_dx (∂RNEA) using CppADCodeGen =\t";
589 timer.
toc(std::cout, NBT);
594 std::remove(
"cg_rnea_eval.dylib");
595 std::remove(
"jit_JSIM.c");
596 std::remove(
"jit_JSIM.so");
597 std::remove(
"jit_JSIM_crba.c");
598 std::remove(
"jit_JSIM_crba.so");
601 std::cout <<
"--" << std::endl;