Differentiating OpenSim models with Enzyme #1870
-
Hello, I work on OpenSim, a musculoskeletal modeling and simulation library used in biomechanics research applications. (A "musculoskeletal" model is essentially a multibody dynamics model with custom actuators to represent muscles and other biological components). OpenSim includes a trajectory optimization library called Moco, and I'm hoping to use Enzyme to differentiate OpenSim models to open the door to solving optimal control problems using automatic differentiation through CasADi. OpenSim is built on top of a separate library, Simbody, a Featherstone-like multibody dynamics engine. Therefore I'm investigating the feasibility of using LLDEnzyme to differentiate functions that bridge the OpenSim and Simbody libraries. I'm also trying to understand if it's possible to differentiate functions with custom data types from OpenSim/Simbody. To test these, I've written the following example: #include <cstdio>
#include <OpenSim/Common/PolynomialFunction.h>
#include <OpenSim/Actuators/DeGrooteFregly2016Muscle.h>
using namespace OpenSim;
extern int enzyme_dup;
extern int enzyme_dupnoneed;
extern int enzyme_out;
extern int enzyme_const;
template < typename return_type, typename ... T >
return_type __enzyme_fwddiff(void*, T ... );
template < typename return_type, typename ... T >
return_type __enzyme_autodiff(void*, T ... );
template < typename T, typename ... arg_types >
auto wrapperMuscle(T obj, arg_types && ... args) {
return obj.calcTendonForceMultiplier(args ... );
}
void testDeGrooteFreglyMuscle() {
DeGrooteFregly2016Muscle muscle;
muscle.finalizeFromProperties();
SimTK::Real y = 1.1;
SimTK::Real dy = 1.0;
SimTK::Real f = muscle.calcTendonForceMultiplier(y);
SimTK::Real dfdy = muscle.calcTendonForceMultiplierDerivative(y);
printf("Muscle analytic derivative\n");
printf("f(y) = %f, f'(y) = %f\n\n", f, dfdy);
dfdy = __enzyme_fwddiff<SimTK::Real>(
(void*)wrapperMuscle<DeGrooteFregly2016Muscle, SimTK::Real>,
enzyme_const, muscle,
enzyme_dup, &y, &dy);
printf("Muscle derivative w/ Enzyme\n");
printf("f(y) = %f, f'(y) = %f\n\n", wrapperMuscle(muscle, y), dfdy);
}
template < typename T, typename ... arg_types >
auto wrapperPolynomial(T obj, arg_types && ... args) {
return obj.calcValue(args ... );
}
void testPolynomialFunction() {
// f = x^2
SimTK::Vector coefficients(3);
coefficients[0] = 1;
coefficients[1] = 0;
coefficients[2] = 0;
PolynomialFunction func(coefficients);
SimTK::Vector y(1, 5.0);
SimTK::Vector dy(1, 1.0);
SimTK::Real dfdy = __enzyme_fwddiff<SimTK::Real>(
(void*)wrapperPolynomial<PolynomialFunction, SimTK::Vector>,
enzyme_const, func,
enzyme_dup, &y, &dy);
printf("PolynomialFunction\n");
printf("f(y) = %f, f'(y) = %f\n\n", wrapperPolynomial(func, y), dfdy);
}
int main() {
testDeGrooteFreglyMuscle();
testPolynomialFunction();
return 0;
}
The second case,
It looks like the name mangling of |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
I have managed to create a minimal CMake-based project that allows Enzyme to compute derivatives through Simbody. I set up the dependencies of this project to use a similar structure as in OpenSim (i.e., built in a separate subdirectory using a separate CMake project). As in OpenSim, the dependencies are built using CMake's Now that this is resolved, I will open a new discussion that is more specific to my latest roadblock. |
Beta Was this translation helpful? Give feedback.
I have managed to create a minimal CMake-based project that allows Enzyme to compute derivatives through Simbody. I set up the dependencies of this project to use a similar structure as in OpenSim (i.e., built in a separate subdirectory using a separate CMake project).
As in OpenSim, the dependencies are built using CMake's
ExternalProject_Add
. I found that in addition to-flto
, I needed to manually pass-DNDEBUG
and-O2
toCMAKE_C_FLAGS
andCMAKE_CXX_FLAGS
. I discovered this after manually building Simbody and these flags appeared by default, but did not appear by default when usingExternalProject_Add
. I am now able to successfully compute the correct derivative of a vector norm when us…