-
-
Notifications
You must be signed in to change notification settings - Fork 168
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
Better Enums with CUDA? #52
Comments
I suspect something is broken with macro expansion in NVCC, but I am not sure yet. I'll point to the most likely offending line. The NVCC output you've pasted includes this: constexpr const Channel _value_array[] = {(Channel::Red = (1)), (Channel::Green), (Channel::Blue)}; This is definitely wrong, looking at the assignment of const Channel _value_array[] = { ((::better_enums::_eat_assign<Channel>)Channel::Red = 1), ((::better_enums::_eat_assign<Channel>)Channel::Green), ((::better_enums::_eat_assign<Channel>)Channel::Blue), }; Clang++ generates that on my system, with |
That specific code is the instantiation of this macro: Lines 494 to 495 in 2fad3f6
Perhaps NVCC doesn't like the nested parentheses? Also, don't mind the missing |
Turns out that it actually works, when I define BETTER_ENUMS_NO_CONSTEXPR before including it. It would still be nice to use BETTER_ENUM with constexpr, I believe NVCC should theoretically support it. I'm pretty sure that this is actually an NVCC problem, but I would request your help in finding the cause of this issue so we can report this to NVIDIA. So here is a document that goes through the NVCC compilation phases, page 22 shows a nice overview over the process. You can watch what NVCC is doing by adding the Both of the C++ intermediate files constexpr const Channel _value_array[] = {
((::better_enums::_eat_assign<Channel>) Channel::Red = 1),
((::better_enums::_eat_assign<Channel>) Channel::Green),
((::better_enums::_eat_assign<Channel>) Channel::Blue), }; Then however, the output file of constexpr const Channel _value_array[] = {(Channel::Red = (1)), (Channel::Green), (Channel::Blue)}; If I understand correctly, cudafe++ does some sort of template parsing, which I gather from the fact that NVCC runs it with the parameter What is it actually supposed to do? |
Turns out it doesn't work. With the following example: #include <iostream>
#define BETTER_ENUMS_NO_CONSTEXPR
#include "enum.h"
BETTER_ENUM(Channel, char, Red /* = 1*/, Green, Blue);
__device__ void calcSomething(int* result, int value, Channel mode) {
switch(mode) {
case Channel::Blue:
*result = 2*value;
break;
default:
*result = 10*value;
}
}
int main() { } I get the following error:
Without the As it looks now, BETTER_ENUMS is simply not compatible with NVCC. |
It's almost certainly the case that NVCC is broken. The point of I don't have the necessary expertise to look into NVCC, unfortunately. But you should be able to copy out the The macro is defined here: Lines 494 to 500 in 2fad3f6
and invoked here: Lines 678 to 679 in 2fad3f6
You should be able to extract all this to a file, for reproducing, pretty easily. Working backwards, to mimic the last bit of code, that creates the array, create a static array somewhere, with the same definition as #define BETTER_ENUMS_TYPE_REPRO(Enum, ...) \
namespace better_enums_data_ ## Enum { \
BETTER_ENUMS_CONSTEXPR_ const Enum _value_array[] = \
{ BETTER_ENUMS_ID(BETTER_ENUMS_EAT_ASSIGN(Enum, __VA_ARGS__)) }; \
} As you can see, you now need to extract only:
That should be self-contained, and enough to find the bug by applying If you want to try building up to the bug instead, try following the explanation of how a simplified Better Enums works in this article: https://stackoverflow.com/questions/28828957/enum-to-string-in-modern-c11-c14-and-future-c17-c20/31362042#31362042. |
Ah, maybe the macro is not involved, as I see the expansion was correct at an earlier step of the NVCC process. But the above steps should get you a relatively simple, self-contained file to work with. Also, I don't know if NVCC is starting over with macros at some point or not. |
This error seems reasonable with
without knowing too much about the semantics of CUDA, I don't know if it makes sense to try adding As for the error with |
...and to give yet more detail about the error you are seeing when Better Enums are objects, and to each Better Enums type |
Hi, I have been trying to use Better Enums with CUDA, in a .cu file.
When supplying
--expt-relaxed-constexpr
to NVCC, this works alright for the most part. However, when initializing the enum members, NVCC does something very strange.Here is my testing code:
Compile with
nvcc constexpr-init.cu -std=c++11 -o constexpr-init
I get the following errors that are not understandable to me:
NVCC creates .cpp files that are passed to the host compiler. These files can be inspected by adding the
--keep
parameter to the command line.If you do that and inspect the file, you will find the macro expansion somewhere, which looks like this:
(Sorry for the no spaces, but this is what I get out).
The error occurs at character 2362 which seems to be the expression
Channel::Red = (1)
in the following statement:This is the end of my investigations, I don't know where to go from here.
I know that it's probably the NVCC that's broken, but can you think of a way to make this initialization work?
The text was updated successfully, but these errors were encountered: