pybind11
pybind11 copied to clipboard
[BUG]: Compiling with `enum_` on CUDA + GCC fails
Required prerequisites
- [x] Make sure you've read the documentation. Your issue may be addressed there.
- [x] Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- [ ] Consider asking first in the Gitter chat room or in a Discussion.
What version (or hash if on master) of pybind11 are you using?
stable
Problem description
I reduced the problem to a very simple snippet (see below; also see the repo with minimal example).
Which fails when cross-compiling with CUDA (I use the Kokkos cross-portability library). Weirdly, this works perfectly fine, if instead of GCC I use LLVM (still with CUDA support ON). If you think this is not a pybind11 issue -- feel free to close, but just wanted to throw this in, as perhaps there is an easy thing I'm overlooking.
Here's the error message with GCC 14 and CUDA 12.8:
/tmp/testenum/extern/pybind11/include/pybind11/pybind11.h: In instantiation of ‘pybind11::enum_<Type>::enum_(const pybind11::handle&, const char*, const Extra& ...) [with Extra = {pybind11::arithmetic}; Type = pybind11_init_enumtest(pybind11::module_&)::ScopedEnum]’:
/tmp/testenum/enumtest.cpp:9:70: required from here
9 | py::enum_<ScopedEnum>(m, "ScopedEnum", py::arithmetic())
| ^
/tmp/testenum/extern/pybind11/include/pybind11/pybind11.h:2237:9: error: ambiguous template instantiation for ‘struct pybind11::detail::initimpl::factory<pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::enum_<pybind11::arithmetic>(const pybind11::handle&, const char*, const pybind11::arithmetic&)::<lambda(pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::Scalar)>, pybind11::detail::void_type (*)(), pybind11_init_enumtest(pybind11::module_&)::ScopedEnum(int), pybind11::detail::void_type()>’
2237 | def(init([](Scalar i) { return static_cast<Type>(i); }), arg("value"));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/testenum/extern/pybind11/include/pybind11/detail/init.h:281:8: note: candidates are: ‘template<class Func, class Return, class ... Args> struct pybind11::detail::initimpl::factory<Func, pybind11::detail::void_type (*)(), Return(Args ...), __remove_pointer(__remove_reference(pybind11::detail::void_type (*)()))> [with Func = pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::enum_<pybind11::arithmetic>(const pybind11::handle&, const char*, const pybind11::arithmetic&)::<lambda(pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::Scalar)>; Return = pybind11_init_enumtest(pybind11::module_&)::ScopedEnum; Args = {int}]’
281 | struct factory<Func, void_type (*)(), Return(Args...)> {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/testenum/extern/pybind11/include/pybind11/detail/init.h:320:8: note: ‘template<class CFunc, class AFunc, class CReturn, class ... CArgs, class AReturn, class ... AArgs> struct pybind11::detail::initimpl::factory<CFunc, AFunc, CReturn(CArgs ...), AReturn(AArgs ...)> [with CFunc = pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::enum_<pybind11::arithmetic>(const pybind11::handle&, const char*, const pybind11::arithmetic&)::<lambda(pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::Scalar)>; AFunc = pybind11::detail::void_type (*)(); CReturn = pybind11_init_enumtest(pybind11::module_&)::ScopedEnum; CArgs = {int}; AReturn = pybind11::detail::void_type; AArgs = {}]’
320 | struct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/testenum/extern/pybind11/include/pybind11/pybind11.h:2237:9: error: invalid use of incomplete type ‘struct pybind11::detail::initimpl::factory<pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::enum_<pybind11::arithmetic>(const pybind11::handle&, const char*, const pybind11::arithmetic&)::<lambda(pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::Scalar)>, pybind11::detail::void_type (*)(), pybind11_init_enumtest(pybind11::module_&)::ScopedEnum(int), pybind11::detail::void_type()>’
2237 | def(init([](Scalar i) { return static_cast<Type>(i); }), arg("value"));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/testenum/extern/pybind11/include/pybind11/detail/init.h:276:42: note: declaration of ‘struct pybind11::detail::initimpl::factory<pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::enum_<pybind11::arithmetic>(const pybind11::handle&, const char*, const pybind11::arithmetic&)::<lambda(pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::Scalar)>, pybind11::detail::void_type (*)(), pybind11_init_enumtest(pybind11::module_&)::ScopedEnum(int), pybind11::detail::void_type()>’
276 | typename = function_signature_t<AFunc>>
| ^~~~~~~
/tmp/testenum/extern/pybind11/include/pybind11/pybind11.h: In instantiation of ‘Ret pybind11::init(Func&&) [with Func = enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::enum_<pybind11::arithmetic>(const pybind11::handle&, const char*, const pybind11::arithmetic&)::<lambda(enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::Scalar)>; Ret = detail::initimpl::factory<enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::enum_<pybind11::arithmetic>(const pybind11::handle&,
const char*, const pybind11::arithmetic&)::<lambda(enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::Scalar)>, detail::void_type (*)(), pybind11_init_enumtest(pybind11::module_&)::ScopedEnum(int), detail::void_type()>]’:
/tmp/testenum/extern/pybind11/include/pybind11/pybind11.h:2237:9: required from ‘pybind11::enum_<Type>::enum_(const pybind11::handle&, const char*, const Extra& ...) [with Extra = {pybind11::arithmetic}; Type = pybind11_init_enumtest(pybind11::module_&)::ScopedEnum]’
2237 | def(init([](Scalar i) { return static_cast<Type>(i); }), arg("value"));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/testenum/enumtest.cpp:9:70: required from here
9 | py::enum_<ScopedEnum>(m, "ScopedEnum", py::arithmetic())
| ^
/tmp/testenum/extern/pybind11/include/pybind11/pybind11.h:1970:1: error: return type ‘struct pybind11::detail::initimpl::factory<pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::enum_<pybind11::arithmetic>(const pybind11::handle&, const char*, const pybind11::arithmetic&)::<lambda(pybind11::enum_<pybind11_init_enumtest(pybind11::module_&)::ScopedEnum>::Scalar)>, pybind11::detail::void_type (*)(), pybind11_init_enumtest(pybind11::module_&)::ScopedEnum(int), pybind11::detail::void_type()>’ is incomplete
1970 | Ret init(Func &&f) {
| ^~~~
make[2]: *** [CMakeFiles/enumtest.dir/build.make:79: CMakeFiles/enumtest.dir/enumtest.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:376: CMakeFiles/enumtest.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
Thanks in advance for you help, and for the cool library you've made!
Reproducible example code
#include <pybind11/pybind11.h>
namespace py = pybind11;
PYBIND11_MODULE(enumtest, m) {
m.doc() = "Test simple enum";
enum class ScopedEnum { Two = 2, Three };
py::enum_<ScopedEnum>(m, "ScopedEnum", py::arithmetic())
.value("Two", ScopedEnum::Two)
.value("Three", ScopedEnum::Three);
}
Is this a regression? Put the last known working version here if it is.
Not a regression