Opened 5 years ago
Closed 4 years ago
#13513 closed Bugs (obsolete)
Nvidia cuda compiler 9 does not work with boost::mp11
Reported by: | Owned by: | ||
---|---|---|---|
Milestone: | To Be Determined | Component: | None |
Version: | Boost 1.66.0 | Severity: | Showstopper |
Keywords: | Cc: |
Description
I am working with cuda and I choose to use boost::mp11 for my projects. However cuda 9 does not work with boost::mp11, even this simple application fails:
#include <boost/mp11.hpp> int main() {}
To be fair, this seems to be a bug in the nvidia compiler not boost, but this is a showstopper for using boost::mp11 together with a recent cuda version. Everything works fine with cuda 8.
I already figured out, what fails in the background in the nvcc (details are here), but now also found a work around for boost::mp11:
The problem occurs on code like this:
template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
Everytime mp_if is used, the nvcc preprocessor tries to be "smart" and starts recursively replacing stuff so that in the end detail::mp_no_type... is given to the compiler.
I figured out I can prevent nvcc from doing this with invoking another struct inbetween like this:
template<template<class...> class F, class... T> struct cuda_workaround { using type = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>; }; template<template<class...> class F, class... T> using mp_defer = typename cuda_workaround< F, T... >::type;
This work around is needed on 5 places in the boost mp11:
- mp_append.hpp
template<class... L> struct mp_append_impl: mp_if_c<(sizeof...(L) > 111), mp_quote<append_inf_impl>, mp_if_c<(sizeof...(L) > 11), mp_quote<append_111_impl>, mp_quote<append_11_impl> > >::template fn<L...>
- algorithm.hpp
template<template<class...> class F, class... L> using mp_transform = typename mp_if<mp_same<mp_size<L>...>, detail::mp_transform_impl<F, L...>, detail::list_size_mismatch>::type;
template<class L, std::size_t I> using mp_at_c = typename mp_if_c<(I < mp_size<L>::value), detail::mp_at_c_impl<L, I>, void>::type;
using type = typename mp_cond< mp_bool<(I < N1)>, mp_nth_element_impl<L1, I, P>, mp_bool<(I == N1)>, mp_identity<T1>, mp_true, mp_nth_element_impl<L2, I - N1 - 1, P> >::type;
- utility.hpp
template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
I added an intermediate struct as seen above for every case if cuda 9 is used and now my code compiles with nvcc 9.
So I suggest to add such a work around for cuda 9 and above. I can also do this myself, what would be the best way? Providing a patch for the most recent version on github or directly opening a pull request?
Change History (2)
comment:1 by , 5 years ago
comment:2 by , 4 years ago
Resolution: | → obsolete |
---|---|
Status: | new → closed |
I opened a PR in the mp11 github: https://github.com/boostorg/mp11/pull/21