stan-dev / math

The Stan Math Library is a C++ template library for automatic differentiation of any order using forward, reverse, and mixed modes. It includes a range of built-in functions for probabilistic modeling, linear algebra, and equation solving.
https://mc-stan.org
BSD 3-Clause "New" or "Revised" License
733 stars 184 forks source link

Conditionally compile cvodes #592

Open seantalts opened 7 years ago

seantalts commented 7 years ago

Summary:

Most Stan programs don't require the cvodes library but we compile it for every model anyway right now.

Description:

I think we should figure out how much time we could save during model compilation by only compiling and linking against cvodes if its needed. I'm assuming specifying the cvodes library as something to include headers from and link against is basically free and that all of the cost would come from just compiling the library. If this is more than ~10% of model compilation time for simple models it might make sense to figure out how to conditionally compile.

I'm creating this issue to track this idea and the results of the above experiment even if we end up deciding it's not worth it.

Current Version:

v2.16.0

seantalts commented 7 years ago

@syclik Have you thought about this much at all? Curious what's already been learned in this area.

bob-carpenter commented 7 years ago

Glad you're looking into this --- it needs to be sorted out anyway for dealing with GPU and MPI code in the near future.

syclik commented 7 years ago

I've put a little thought into it. This is in the math repo, but I'm assuming the bigger issue is from the interfaces. I've already started the process for the math repo in the open pull request for implicit rules: #582.

In the math repo, the right way to do it using make is to add a dependency on the libraries for the cvodes headers within Stan. That's adding something like:

stan/math/rev/mat/functor/cvodes_ode_data.hpp stan/math/rev/mat/functor/cvodes_utils.hpp: $(LIBCVODES)

You can see the more general version (by using find) here. There's a corresponding fix to add it to the tests LDFLAGS here: make/tests. Those are both on the pull request, so aren't in math's develop branch yet.

Unfortunately, this won't work for the CmdStan or the other interfaces as-is. We include a top-level include for all Stan programs which includes the cvodes header files. I think we could manage if we generated different top-level includes for whether it had CVODES (or GPU or MPI). We could then add the library dependencies to those particular header files, which would then drive make to include them.

CVODES is slightly different than GPU and MPI because if CVODES isn't installed and a user wants to run a program, there's no elegant degradation. (We could if we swapped the CVODES solver for the boost solver.) For GPU and MPI, if the libraries don't exist, we want them to run the CPU equivalent code.

bob-carpenter commented 7 years ago

On Aug 1, 2017, at 7:47 PM, Daniel Lee notifications@github.com wrote:

I've put a little thought into it.

I'm glad to hear that.

CVODES is slightly different than GPU and MPI because if CVODES isn't installed and a user wants to run a program, there's no elegant degradation.

Can't the ode_integrate function just throw an exception if it's not installed.

After that, I think it's just different behavior after branching than the GPU/MPI code. The GPU and MPI code can fall back to a serial implementation.

But it should look the same from the build process, right? We'll get some flag down in the code that's on if the thing's installed (or if it's not---don't care which way the logic goes, though usually positive is easier to think about for me).

betanalpha commented 7 years ago

My understanding is that many of the text interrogation functions were originally implemented for conditional compile functionality. So we’d have the parser also generate a necessary-library file which make could search to see which compiler options it uses and then against which shared libraries it tries to link.

On Aug 1, 2017, at 6:03 PM, Bob Carpenter notifications@github.com wrote:

On Aug 1, 2017, at 7:47 PM, Daniel Lee notifications@github.com wrote:

I've put a little thought into it.

I'm glad to hear that.

CVODES is slightly different than GPU and MPI because if CVODES isn't installed and a user wants to run a program, there's no elegant degradation.

Can't the ode_integrate function just throw an exception if it's not installed.

After that, I think it's just different behavior after branching than the GPU/MPI code. The GPU and MPI code can fall back to a serial implementation.

But it should look the same from the build process, right? We'll get some flag down in the code that's on if the thing's installed (or if it's not---don't care which way the logic goes, though usually positive is easier to think about for me).

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/stan-dev/math/issues/592#issuecomment-319510374, or mute the thread https://github.com/notifications/unsubscribe-auth/ABdNln3Jsldu8wK_Icp2BmQ8EHKTUP1Dks5sT6C9gaJpZM4Oo_mg.

wds15 commented 6 years ago

Would dynamic linking vs the cvodes library (instead of static linking now) speed up the linking process? This would be another way to speed up compilation and if the answer is yes to that, then I am happy to open another issue for this.

bob-carpenter commented 6 years ago

I don't know. Would you mind benchmarking?

We need to start thinking about general ways to speed up compiles. Right now, most of our time's sunk dealing with the header compilation, much of which could be redone. One of my to-do items as we refactor the underlying language and model class is to introduce enough instantiated virtuals that we can precompile the algorithms.

seantalts commented 6 years ago

http://www.bitsnbites.eu/faster-c-builds/