jll63 / yomm2

Fast, orthogonal, open multi-methods. Solve the Expression Problem in C++17.
Boost Software License 1.0
343 stars 18 forks source link

Boost 1.53 compatibility #11

Closed derpda closed 4 years ago

derpda commented 4 years ago

First off, I realize that yomm2 dependencies clearly state that Boost 1.65 or later is recommended. However, the supercomputers which our library is intended to be used on have older versions installed, specifically 1.54 on TSUBAME and 1.53 on ABCI. Supercomputers having old library versions installed is a sad fact of the field.

Poblem

The issue is, Boost 1.53/1.54 do not have boost/preprocessor/tuple/push_front.hpp yet. It was added 1.56 (ouch, so close...).

That header only contains the following definition

# include <boost/preprocessor/array/push_front.hpp>
# include <boost/preprocessor/array/to_tuple.hpp>
# include <boost/preprocessor/tuple/to_array.hpp>

# define BOOST_PP_TUPLE_PUSH_FRONT(tuple, elem) \
    BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_PUSH_FRONT(BOOST_PP_TUPLE_TO_ARRAY(tuple), elem)) \
/**/

This is a simple convenience routine transforming the tuple into an array, using array's push_front to add an element, and finally transforming the resulting array back into a tuple. If I simply replace BOOST_PP_TUPLE_PUSH_FRONT with its definition and include the additional headers, I can compile yomm2 with the old boost version without issues.

Suggestion

Use new header if available (check Boost version). If not available, define the needed function.

#if Boost_VERSION_MINOR >= 56
#include <boost/preprocessor/tuple/push_front.hpp>
#else
#include <boost/preprocessor/array/push_front.hpp>
#include <boost/preprocessor/array/to_tuple.hpp>
#include <boost/preprocessor/tuple/to_array.hpp>
#define BOOST_PP_TUPLE_PUSH_FRONT(tuple, elem) BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_PUSH_FRONT(BOOST_PP_TUPLE_TO_ARRAY(tuple), elem))
#endif

I realize this is somewhat ugly and might not be something you want to include, but it would help greatly in my case since compiling a newer boost version as a non-root user is significant effort. We don't want to force users of our library on supercomputers to build boost first and fiddle around with paths. Moving back to yomm11 is an option for us, but we would like to avoid that.

jll63 commented 4 years ago

Yeah I would also like to avoid you having to revert to yomm11. I wonder, though, how it would compare against yomm2 in terms of performance. yomm11 has a bit of an edge on yomm2 because of the pointer it plants in the object. However, when a good compiler is used (have you looked at the machine code that is generated for a 1-method call?) and the method performs any significant amount of work, I would not expect the difference to be observable. Since we're at it, do you have feedback regarding performance?

Back to your problem...It looks like TUPLE_PUSH_FRONT is used only in class registration, which is not the most complicated bit of macro-fu. I wonder if it would be possible to rewrite it without using that macro. But it also uses TUPLE_REM, is that one part of 1.56?

Also, IIRC the reason why yomm2 depends on Boost 1.65 is Boost.Test. 1.56 won't have it. Is that a problem for you?

jll63 commented 4 years ago

Can you try this branch with your old Boost? In the meantime I will download Visual C++ and test it on Windows. https://github.com/jll63/yomm2/tree/boots-1.53-compatibility

derpda commented 4 years ago

I was actually not at all worried about the performance, but only about the convenience of users of our library! On the topic of performance though, I have done some measurements and if any significant work is done (which is the case for our library as it performs matrix calculations), the impact of yomm2 is so small that I couldn't really measure it. The actual algebraic operations (BLAS/LAPACK calls) that our code performs account for 99% of wall time for matrices of the size we are interested in. The remaining 1% however includes things other than yomm as well. So further optimization of the yomm speed are really not a concern for us!

About the Boost version: It's totally OK for us if users with old Boost cannot compile the yomm tests. With the changes I suggested in my original post, I was able to compile yomm and use our library without issues, so it seems that TUPLE_PUSH_FRONT was the only part breaking backwards compatibility. Even though the class registration might be the least complicated macro-fu in yomm, the best I could come up with was this stopgap solution.

In the meantime, I tried building with https://github.com/jll63/yomm2/tree/boots-1.53-compatibility and had no issues! If the changes work for other users of the library and don't cause issues, it would be awesome if they could be merged into master! =)

jll63 commented 4 years ago

On the topic of performance though, I have done some measurements and if any significant work is done (which is the case for our library as it performs matrix calculations), the impact of yomm2 is so small that I couldn't really measure it.

I'm delighted to hear that ;-)

In the meantime, I tried building with https://github.com/jll63/yomm2/tree/boots-1.53-compatibility and had no issues! If the changes work for other users of the library and don't cause issues, it would be awesome if they could be merged into master! =)

I tested with VS 2019, no issues. Merged.