Including the fmt header using nvcc CUDA compiler with msvc 2017 triggers the following compiling errors:
...\fmt\core.h(662): error C2059: syntax error: '
'
...\fmt\core.h(662): error C2062: type 'unknown-type' unexpected
...\fmt\core.h(662): error C2143: syntax error: missing ';' before '{'
...\fmt\core.h(662): error C2447: '{': missing function header (old-style formal list?)
...\fmt\core.h(666): error C2059: syntax error: ''
...\fmt\core.h(666): error C2062: type 'unknown-type' unexpected
...\fmt\core.h(666): error C2143: syntax error: missing ';' before '{'
...\fmt\core.h(666): error C2447: '{': missing function header (old-style formal list?)
The parse error can be resolved by rewriting FMT_MAKE_VALUE macro manually using SFINAE, but after that nvcc emits a new bunch of errors. Both gcc+nvcc and clang under Linux work fine.
I think this is similar with # 1080.
MSVC version: 2017 15.9.11
nvcc version: V10.1.105
Compile command used: nvcc -DFMT_HEADER_ONLY=1 -isystem=... -D_WINDOWS .\test-fmt.cu
Error code:
#include <fmt/core.h>
int main() {
return 0;
}
I'm not familiar with CUDA but PRs to fix/workaround this are welcome.
Hello @hbsnmyj, I'm interested in this issue.
I created a new test for importing fmt in CUDA source code. This is the commit: https://github.com/luncliff/fmt/commit/ba82f542d61073d36ab17bc3a86f530d7e59d739
I can't provide my build/test log since Windows CI services don't support CUDA.
But you can try with my fork.
For now it seems like suppressing FMT_DEPRECATED makes the code compilable.
static_assert(__cplusplus >= 201402L, "expect C++ 2014 for nvcc");
#if defined(__CUDACC__)
# define FMT_DEPRECATED
#endif
#include <fmt/core.h>
#include <cuda.h>
#include <iostream>
using namespace std;
extern auto make_message_cpp() -> std::string;
extern auto make_message_cuda() -> std::string;
int main(int, char*[]){
cout << make_message_cuda() << endl;
cout << make_message_cpp() << endl;
}
auto make_message_cuda() -> std::string{
return fmt::format("nvcc \t: __cplusplus == {}", __cplusplus);
}
I'd like to try your alternative (which used SFINAE), could you provide the code here if you still have it?
Thanks in advance.
@vitaut, would it be critical if users suppress FMT_DEPRECATED like the comment above?
We can consider adding check for __CUDACC__ macro in the header file, but I think we had better avoid the solution since NVCC has a gap from major C++ compilers.
I believe most of the CUDA source codes are being maintained in a relatively small pieces.
And they can use some extern functions which implements string rendering instead of including fmt's headers in .cu source codes
would it be critical if users suppress FMT_DEPRECATED like the comment above?
I think it's a reasonable workaround, so I'll be happy to accept a PR that does this (with a short explanatory comment). I'm about to add a similar workaround for the Intel compiler that doesn't understand [[deprecated]] in type aliases.
@hbsnmyj, does the newly added cuda-test work on your system?
Closing for now since the test shows that {fmt} can work with CUDA. If you still get an error feel free to reopen but please provide more repro details, particularly the {fmt} version/commit.