variant icon indicating copy to clipboard operation
variant copied to clipboard

Can't build mpark::visit under cuda compiler

Open ryderblue opened this issue 5 years ago • 7 comments

I'm trying to build code using mpark::visit, which compiles fine under gcc/clang, but fails to compile with CUDA compiler:

visit-test.cpp(11): error: no instance of function template "mpark::visit" matches the argument list
            argument types are: (Visit, mpark::variant<int>)

I installed CUDA compiler on Ubuntu 18.04:

$ sudo apt-get install nvidia-cuda-toolkit
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Nov__3_21:07:56_CDT_2017
Cuda compilation tools, release 9.1, V9.1.85

Simple example:

#include <mpark/variant.hpp>

struct Visit {
  std::string operator()(int i) const {
    return "int";
  }
};

void test() {
  mpark::variant<int> i(1);
  mpark::visit(Visit{}, i);
}

Here's the gist with makefile: https://git.zooxlabs.com/gist/rrishel/cbfb122a65cdb629f89233e1fa2bc96c

ryderblue avatar Mar 25 '19 17:03 ryderblue

FWIW, building same example using boost::variant works:

#include <boost/variant.hpp>

struct Visit : public boost::static_visitor<std::string> {
  std::string operator()(int i) const {
    return "int";
  }
};

void test() {
  boost::variant<int> i(1);
  boost::apply_visitor(Visit{}, i);
}

ryderblue avatar Mar 25 '19 17:03 ryderblue

Still fails with nvcc 10.2.89, but with a different error message:

variant.hpp: In function ‘constexpr decltype(auto) mpark::visit(Visitor&&, Vs&& ...)’:
variant.hpp:2674:96: error: parameter packs not expanded with ‘...’:
     return (detail::all({!vs.valueless_by_exception()...})
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                     ^                                                                                                      
variant.hpp:2674:96: note:         ‘vs’

As a workaround, you can replace the implementation of the visit function

  template <typename Visitor, typename... Vs>
  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
    return (detail::all({!vs.valueless_by_exception()...})
                ? (void)0
                : throw_bad_variant_access()),
           detail::visitation::variant::visit_value(
               lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
  }

with this:

  template <typename Visitor, typename... Vs>
  inline constexpr decltype(auto) visit(Visitor &&visitor, Vs &&... vs) {
    return (detail::all(std::initializer_list<bool>({!vs.valueless_by_exception()...}))
                ? (void)0
                : throw_bad_variant_access()),
           detail::visitation::variant::visit_value(
               lib::forward<Visitor>(visitor), lib::forward<Vs>(vs)...);
  }

Note that nvcc has problems with the variadic brace-initializer. I've already reported the problem for nvcc 9.2.88 but it seems that the same bug reappeared...

lahwaacz avatar Jan 30 '20 12:01 lahwaacz

Does #73 fix this?

dholladay00 avatar Feb 19 '20 01:02 dholladay00

Yes, it seems to work with https://github.com/mpark/variant/blob/d1cdfdd3f2ed80710ba4d671fe6bffaa3e28201a/master/variant.hpp

lahwaacz avatar Feb 20 '20 15:02 lahwaacz

I actually am getting errors of the following form:

error: calling a __host__ function("mpark::detail::copy_assignment< ::mpark::detail::traits<....

I am currently able to work around this by adding __host__ __device__ to copy_assign at lines 1420 and 1424 of variant.hpp

I imagine there are better solutions to this, anyone else run into this?

dholladay00 avatar Jul 07 '20 00:07 dholladay00

@dholladay00 Which version of variant.hpp are you using? And please show the full error, there is not even a full signature of the function where it fails...

lahwaacz avatar Jul 07 '20 06:07 lahwaacz

I am using the latest master of mpark variant with Cuda 10.1.

Here is a more detailed version of the error(s):

error: calling a __host__ function("mpark::detail::copy_assignment< ::mpark::detail::traits< ... > , ( ::mpark::detail::Trait)1> ::operator =") from a __device__ function("Kokkos::Impl::ParallelFor< ::Kokkos::Impl::ViewCopy< ::Kokkos::View< ... >  *,  ::Kokkos::LayoutLeft,  ::Kokkos::Device< ::Kokkos::Serial,  ::Kokkos::AnonymousSpace> ,  ::Kokkos::MemoryTraits<(unsigned int)0u>  > ,  ::Kokkos::LayoutRight,  ::Kokkos::Cuda, (int)1, long, (bool)0> ,  ::Kokkos::RangePolicy< ::Kokkos::Cuda,  ::Kokkos::IndexType<long>  > ,  ::Kokkos::Cuda> ::operator () const") is not allowed
error: identifier "mpark::detail::copy_assignment< ::mpark::detail::traits< ... > , ( ::mpark::detail::Trait)1> ::operator =" is undefined in device code

along with some warnings along these lines:

/.../include/mpark/variant.hpp(1052): warning: calling a __host__ function("mpark::detail::destructor< ::mpark::detail::traits< ... > , ( ::mpark::detail::Trait)1> ::~destructor") from a __host__ __device__ function("mpark::detail::destructor< ::mpark::detail::traits< ... > , ( ::mpark::detail::Trait)1> ::~destructor [subobject]") is not allowed

dholladay00 avatar Jul 07 '20 15:07 dholladay00