-
-
Notifications
You must be signed in to change notification settings - Fork 190
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
Allow users to specify lib & include paths for all dependencies #2834
Conversation
This is awesome! Very cool to also have it tested in CI |
The tests are failing due to the issue #2836 resolved, if you're able to merge |
@WardBrian when you've got a minute would you be able to check whether my last updates fix sundials for you? |
@andrjohns the instances of E.g., for the algebra solver tests on like 86 $(ALGEBRA_SOLVER_TESTS) : $(SUNDIALS_TARGETS)
$(ALGEBRA_SOLVER_TESTS) : LDLIBS += $(LIBSUNDIALS) Additionally, before this is usable from CmdStan, |
Good catch! Pushed that update now, and then should be ready to review (assuming tests pass!) I'll update those |
I've read over the makefile changes, which all seem reasonable. I'm not confident enough to say whether the use of |
Thanks for the help so far @WardBrian! @wds15 When you've got a minute would you be able to look over the backwards-compatibility changes to the SUNDIALS code in this PR? It's just @bob-carpenter and @rok-cesnovar could I ask for your higher-level perspective on whether this version-checking approach fits in the Stan ecosystem? Background below: As part of allowing users to provide external dependencies we need to perform some compatibility-checking (either erroring outright, or setting flags for the pre-processor). We can't do this purely through the Makefile since we have to check the values/macros set by the external dependencies (e.g., Does that sound reasonable or is there a better approach that I'm missing? Thanks! |
Don't the libraries already have environment variables in the makefiles for their location?
I didn't understand the description of the solution or what exactly was being proposed for |
Are these sundials ifdefs introduced to make things work with older sundials versions? not sure we want to support multiple versions..the next sundials version bump will require again changes to the code due to their new logger stuff. So keeping things working with the latest sounds like enough to worry about for me. |
Yep. The versions of SUNDIALS packaged in most distros at their current/latest release is still at 5.8.0:
If there are major API changes in the next Sundials versions and the benefits are worth sacrificing backwards-compatibility completely, we can restrict the minimum Sundials version. But I'd prefer not to do that if possible - since it makes packaging and portability for users a bit trickier |
There have been several requests for linking/compiling Stan Math against external/system versions of the dependencies, rather than the bundled Eigen/Boost/Sundials/TBB. The issue here is that the versions of these dependencies in package repos (or on cluster) can lag behind, so we need to include compatibility checks if a user attempts to use the Math library with a version of the dependency that's too old.
These are defined as macros in the library's C/C++ headers, not environment variables, so they need to be checked by the pre-processor before it trying to compile.
Because these version macros need to be processed/checked before the compiler encounters incompatible code, my solution was to force the compilation to process the macros first. The macro checks are implemented in |
Is it really needed that all libraries are coming from the OS? Why can't we make Sundials being linked from the OS only if the version is new enough and all other cases we just take the shipped one? Sundials is very unproblematic as we link statically to it. And yes, the next Sundials version comes with improvements which could be nice to have ... and it requires again changes to the source (I tried already to upgrade and it failed given our current source). |
Sundials has been the hang up for me in my previous couple attempts to compile Stan with MSVC on windows. That said, I can use the same version we do from something like Conda, I’m not relying on system package repos. I think that the version.hpp trick is useful even if we don’t want to support older versions, since detecting them and then using |
That's fair, I can drop the Sundials changes and just set the version check to error. My eventual goal is to package CmdStan, Stan, and Math for linux distros, with packages for the headers repos and cmdstan binaries like:
So for Stan Math I can just have patches like those currently in this PR for Sundials compatibility. Note that I'll be opening a design doc for this once I've added external dependency linking to both |
@hsbadr do you have any suggestions/issues with this PR? You were the one that originally introduced the external TBB compatibility, so let me know if any of this conflicts with your perspective of how things should be handled |
@syclik would you be able to review this PR? For allowing the Math library to link to external dependencies |
Yup. |
@andrjohns, I'm going to leave a bunch of comments. Mind if we have a chat? or can you summarize the goals of what you're trying to accomplish? I see something like this and I know it's not possible:
at least not the way things are done right now. So... before spinning wheels a whole lot, let's chat about it. Let me know how you want to meet. Slack? Video? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrjohns, it looks like most of the PR isn't necessary; I think we can just use the existing makefile without most of these changes.
At the very least, we should be documenting it better so you know that this is all possible.
wget http://ftp.de.debian.org/debian/pool/main/e/eigen3/libeigen3-dev_3.3.9-2_all.deb | ||
sudo dpkg -i ./libeigen3-dev_3.3.9-2_all.deb | ||
sudo apt-get install -y libboost-all-dev libtbb-dev ocl-icd-libopencl1 ocl-icd-opencl-dev opencl-c-headers opencl-clhpp-headers | ||
echo "EIGEN_INC=/usr/include/eigen3/" >> make/local |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[EIGEN_INC]: We don't need a new variable. This is literally the existing EIGEN
make variable. Unless we want this to be renaming all the includes.
sudo dpkg -i ./libeigen3-dev_3.3.9-2_all.deb | ||
sudo apt-get install -y libboost-all-dev libtbb-dev ocl-icd-libopencl1 ocl-icd-opencl-dev opencl-c-headers opencl-clhpp-headers | ||
echo "EIGEN_INC=/usr/include/eigen3/" >> make/local | ||
echo "BOOST_INC=/usr/include/" >> make/local |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[BOOST_INC]: this should just be BOOST
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missing the proper include directory.
sudo apt-get install -y libboost-all-dev libtbb-dev ocl-icd-libopencl1 ocl-icd-opencl-dev opencl-c-headers opencl-clhpp-headers | ||
echo "EIGEN_INC=/usr/include/eigen3/" >> make/local | ||
echo "BOOST_INC=/usr/include/" >> make/local | ||
echo "TBB_INC=/usr/include/" >> make/local |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[TBB_INC]: this is the same as the TBB
variable. We should just use that. Also, this isn't pointing to the proper include directory.
echo "EIGEN_INC=/usr/include/eigen3/" >> make/local | ||
echo "BOOST_INC=/usr/include/" >> make/local | ||
echo "TBB_INC=/usr/include/" >> make/local | ||
echo "TBB_LIB=/usr/lib/86_64-linux-gnu" >> make/local |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks wrong for the TBB include library (By inspection). An example from doxygen:
TBB_LIB="$TBB/lib/intel64/gcc4.8"
I'd expect there to be a TBB somewhere.
echo "BOOST_INC=/usr/include/" >> make/local | ||
echo "TBB_INC=/usr/include/" >> make/local | ||
echo "TBB_LIB=/usr/lib/86_64-linux-gnu" >> make/local | ||
echo "OPENCL_INC=/usr/include/" >> make/local |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[OPENCL_INC]: this should just be OPENCL
and the include is not correct.
CXXFLAGS_SUNDIALS ?= -pipe $(CXXFLAGS_OPTIM_SUNDIALS) $(CPPFLAGS_FLTO_SUNDIALS) | ||
#CXXFLAGS_GTEST | ||
|
||
ifdef BOOST_INC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should remove this variable in favor of just using the BOOST
variable. There's no need to do this if statement.
Let's chat if you need help understanding how make works. (The doc is really tough to understand, so happy to walk you through it.) There are two things that really stand out that we shouldn't do here:
ifdef BOOST_INC
... the?=
is the operator you want to use.CXXFLAGS
... we're not including the C++ includes in our CXX flags. We've managed to get things consistenly split out by havingINC_*
and separating that fromCXXFLAGS_*
. There really aren't codified rules for make anywhere, but let's follow how make itself uses these variables and their naming convention so we look more standard than just inventing a bunch of stuff that makes it harder to manage than it already is.
CXXFLAGS_BOOST ?= -I $(BOOST) | ||
endif | ||
|
||
ifdef SUNDIALS_LIB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as above
CXXFLAGS_SUNDIALS += $(INC_SUNDIALS) | ||
endif | ||
|
||
ifdef SUNDIALS_INTERFACE_OLD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
??? what's SUNDIALS_INTERFACE_OLD
?
this looks like some testing that got included.
@@ -23,7 +23,7 @@ CPPLINT ?= $(MATH)lib/cpplint_1.4.5 | |||
# Fortran bindings which we do not need for stan-math. Thus these targets | |||
# are ignored here. This convention was introduced with 4.0. | |||
## | |||
|
|||
ifndef SUNDIALS_LIB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't be necessary.
#include <tbb/version.h> | ||
#endif | ||
|
||
#if EIGEN_VERSION_AT_LEAST(3, 4, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it'll be useful, but maybe not done this way? I'm not sure if this is where we should check. Maybe it is. Can you walk through the logic?
@andrjohns, I think you should be able to do what you're trying to do with the existing makefile. Were you not able to? |
I know that our existing makefiles aren't able to link against sundials as a shared library, which this makes it able to |
Thanks for the example. Mind being more specific? I don't see anything in this PR that would enable that behavior where the original didn't... I could be missing something. (if there's a discourse thread or something to show the shared library linking instructions, let me know and I'll try to replicate.) |
It was discussed earlier in this PR: #2834 (comment) The short version is we currently link to sundials by explicitly passing the paths to the |
@WardBrian, thanks for the link to the comment.
At the very least, it'd be more consistent with the rest of the flags by using |
Summary
This PR adds the ability for users to specify the include and library paths for all dependencies, identical to that provided by the
TBB_INC
andTBB_LIB
flags.This will also eventually be used for linking against system-installed versions of the dependencies.
The new flags are:
EIGEN_INC
BOOST_INC
SUNDIALS_INC
SUNDIALS_LIB
OPENCL_LIB
OPENCL_INC
This PR also implements some basic version-checking for compatibility, and automatically setting
define
s for thesundials
andTBB
libraries.Tests
An additional Github Actions workflow has been added for testing
fwd
/rev
/mix
functions with system libraries.Side Effects
The compiler flags have been altered so that the
stan/math/version.hpp
file is included first, so that the library versions and flags can be correctly tested/setRelease notes
Added
EIGEN_INC
,BOOST_INC
,SUNDIALS_INC
,SUNDIALS_LIB
,OPENCL_LIB
,OPENCL_INC
Makeflags for linking to system/external librariesChecklist
Math issue Allow Math library to link to system-installed libraries/headers #2518
Copyright holder: Andrew Johnson
The copyright holder is typically you or your assignee, such as a university or company. By submitting this pull request, the copyright holder is agreeing to the license the submitted work under the following licenses:
- Code: BSD 3-clause (https://opensource.org/licenses/BSD-3-Clause)
- Documentation: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
the basic tests are passing
./runTests.py test/unit
)make test-headers
)make test-math-dependencies
)make doxygen
)make cpplint
)the code is written in idiomatic C++ and changes are documented in the doxygen
the new changes are tested