Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/issue 512 speedup ode #513

Merged
merged 3 commits into from
Apr 3, 2017
Merged

Conversation

wds15
Copy link
Contributor

@wds15 wds15 commented Mar 22, 2017

Submission Checklist

  • Run unit tests: ./runTests.py test/unit
  • Run cpplint: make cpplint
  • Declare copyright holder and open-source license: see below

Summary:

Internal changes to the non-stiff ODE solver which speedup ODE integration whenever the ODE RHS side is costly to evaluate. This is the case whenever complicated forcing functions are involved. For example, a dosing schedule in PK/PD models.

Intended Effect:

Make non-stiff ODE integration faster. This is realized by avoiding duplicate evaluation of the ODE RHS whenever the ODE integrator calls the () operator of the coupled_ode_system.

How to Verify:

Look at code changes and run tests

  • test/unit/math/rev/arr/functor/coupled_ode_system_test.cpp
  • test/unit/math/prim/arr/functor/coupled_ode_system_test.cpp

To observe the speedup I have run a benchmark which involves a costly ODE RHS and the execution time goes down from 3.51h (2.14.0) to 2.38h (this branch) which is a ~50% speed increase.

The tests required a minor adjustment. The old test code passed a dy_dt into the coupled_ode_system () operator which had the size of the base system. However, odeint will always pass in a vector as dy_dt into the coupled ode system () operator which is as large as the coupled system and expect that this vector is updated. Hence, we can do the update in-place instead of doing a reallocation which was done before. Therefore, tests need to pass a vector into the () operator which corresponds in size to the coupled ode system, i.e. the vector must be as large as the initial_state vector.

Side Effects:

None.

Documentation:

Reviewer Suggestions:

Anyone.

Copyright and Licensing

Please list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company): Sebastian Weber

By submitting this pull request, the copyright holder is requiring to license the submitted work under the following licenses:

@bob-carpenter
Copy link
Contributor

I can review this early next week after the ONR grant gets done. Or someone else might do it sooner. @syclik or @betanalpha perhaps?

@wds15
Copy link
Contributor Author

wds15 commented Mar 23, 2017

Sooner is always better, but early next week would be great, Bob. Then it should be available with 2.15.

Thanks.

@bob-carpenter
Copy link
Contributor

bob-carpenter commented Mar 23, 2017 via email

Copy link
Contributor

@bob-carpenter bob-carpenter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. There was only a comment, not a change request---I'm just curious how boost::ref helps where you used it. I'm going to approve and merge, but I'd still like to know!

@@ -127,7 +127,7 @@ namespace stan {
double,
std::vector<double>,
double>() ),
coupled_system,
boost::ref(coupled_system),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a change request, just a question: Is this boost::ref because you're calling boost::numeric::odeint::integrate_times on the coupled system and don't want to make a copy (I see that integrate_times just takes the system, not a system reference)? Does it actually prevent copying?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi!

odeint does lots of copy-constructions of the ode RHS functor. The author of odeint claims that with compiler optimizations this will make sure that code being generated is faster. However, I have observed the reverse. That is, since we have some instances as copies inside the ode rhs functor, lots of copies are being made of these during the ode integration. I noticed a few % speedup when using boost::ref. So I am not saving a single, but many copies.

Sebastian

@bob-carpenter bob-carpenter merged commit 0e76abd into develop Apr 3, 2017
@bob-carpenter bob-carpenter deleted the feature/issue-512-speedup-ode branch April 3, 2017 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants