Skip to content
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

Non C++17 CUDA compilation is broken when STL headers are included #2020

Closed
gevtushenko opened this issue Jun 22, 2021 · 20 comments
Closed

Non C++17 CUDA compilation is broken when STL headers are included #2020

gevtushenko opened this issue Jun 22, 2021 · 20 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@gevtushenko
Copy link

Hello, I'm using fresh VS install (16.10.2). When I compile the following code sample everything is fine:

#include <stdio.h>

int main() {
    printf("+");
    return 0;
}

But STL usage:

#include <string>

int main() {
    return static_cast<int>(std::string("hello").size());
}

leads to the following compilation errors

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xmemory(62): error: expected a "("
          detected during:
            instantiation of "size_t std::_Get_size_of_n<_Ty_size>(size_t) [with _Ty_size=16ULL]" 
(839): here
            instantiation of "_Ty *std::allocator<_Ty>::allocate(size_t) [with _Ty=std::_Container_proxy]" 
(1321): here
            instantiation of "std::_Container_proxy_ptr12<_Alloc>::_Container_proxy_ptr12(_Alloc &, std::_Container_base12 &) [with _Alloc=std::_Rebind_alloc_t<std::_Rebind_alloc_t<std::allocator<char>, char>, std::_Container_proxy>]" 
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xstring(2501): here
            instantiation of "std::basic_string<_Elem, _Traits, _Alloc>::basic_string(const _Elem *, std::basic_string<_Elem, _Traits, _Alloc>::size_type) [with _Elem=char, _Traits=std::char_traits<char>, _Alloc=std::allocator<char>]" 
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xstring(4997): here

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xutility(131): error: expected a "("
          detected during:
            instantiation of "void *std::_Voidify_iter(_Iter) [with _Iter=std::_Container_proxy *]" 
(158): here
            instantiation of "void std::_Construct_in_place(_Ty &, _Types &&...) [with _Ty=std::_Container_proxy, _Types=<std::_Container_base12 *>]" 

If I change the standard version to C++17 - everything works fine. It seems that there is an unguarded if constexpr usage in the STL.

@miscco
Copy link
Contributor

miscco commented Jun 22, 2021

We have indeed switched completely to using if constexpr

This should be fine as it only results in a warning that is suppressed project wide.

Are you sure you are using a supported Version of CUDA? AFAIK we require 10.2

@gevtushenko
Copy link
Author

We have indeed switched completely to using if constexpr

This should be fine as it only results in a warning that is suppressed project wide.

Are you sure you are using a supported Version of CUDA? AFAIK we require 10.2

In the CUDA installation guide it's said that CUDA 11.3 is supported by Visual Studio 2019 16.x on x86_64 systems. I'm using CUDA 11.3.109.

@miscco
Copy link
Contributor

miscco commented Jun 22, 2021

Did you pass the required --expt-relaxed-constexpr flag?

@gevtushenko
Copy link
Author

Did you pass the required --expt-relaxed-constexpr flag?

It's said that --expt-relaxed-constexpr "allow host code to invoke __device__constexpr functions, and device code to invoke __host__constexpr functions". In the example above all the source code is written for host only. Why is it required in this case?

@miscco
Copy link
Contributor

miscco commented Jun 22, 2021

Because if constexpr simplifies library code tremendously. In fact the benefit is so huge that it is required for the STL also with clang and MSVC

@gevtushenko
Copy link
Author

Because if constexpr simplifies library code tremendously. In fact the benefit is so huge that it is required for the STL also with clang and MSVC

Right, it's the motivation for the if constexpr. I asked why should --expt-relaxed-constexpr be required in the sample above. There is no call to device constexpr function from the host one and vice versa.

@miscco
Copy link
Contributor

miscco commented Jun 22, 2021

if constexpr is a C++17 feature and as far as I understand it that flag enables it for C++14

@gevtushenko
Copy link
Author

if constexpr is a C++17 feature and as far as I understand it that flag enables it for C++14

Is there documentation that states that this option enables if constexpr for C++14? I've tried it and it doesn't seem to help.

@fsb4000
Copy link
Contributor

fsb4000 commented Jun 22, 2021

Strange. It looks fine for me in the compiler explorer:
https://gcc.godbolt.org/z/e53e79Gvz

(I have not installed CUDA Toolkit yet)

@gevtushenko
Copy link
Author

Strange. It looks fine for me in the compiler explorer:
https://gcc.godbolt.org/z/e53e79Gvz

(I have not installed CUDA Toolkit yet)

Godbolt uses GCC. I don't have any issues with GCC build.

@fsb4000
Copy link
Contributor

fsb4000 commented Jun 22, 2021

@senior-zero.
Can't reproduce:

$ type main.cu
#include <string>

int main() {
  return static_cast<int>(std::string("hello").size());
}

$ "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\bin\nvcc.exe" -gencode=arch=compute_52,code=\"sm_52,compute_52\" --use-local-env -ccbin "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64"    -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\include" -I"C:\tools\vcpkg\scripts\buildsystems\msbuild\..\..\..\installed\x64-windows\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\include"  -maxrregcount=0  --machine 64 --compile -cudart static    -DWIN32 -DWIN64 -DNDEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /O2  /FS   /MD "  main.cu
main.cu

изображение

Default Cuda Project from Visual Studio 2019 Community 16.10.2 also builds fine.
изображение

изображение

изображение

@StephanTLavavej StephanTLavavej added bug Something isn't working help wanted Extra attention is needed labels Jun 23, 2021
@StephanTLavavej
Copy link
Member

Our test coverage currently uses CUDA 10.1 Update 2 in C++14 mode (it didn't support C++17) without any special flags to enable if constexpr, as far as I know (at our request, the CUDA team enabled this feature in C++14 mode, for parity with MSVC):

#error STL1002: Unexpected compiler version, expected CUDA 10.1 Update 2 or newer.

If this isn't working in CUDA 11.3 and @fsb4000 can't repro, then we'll need to find out what the necessary conditions for the repro are.

@gevtushenko
Copy link
Author

Hello @StephanTLavavej, @fsb4000! The build is successful when it's launched from VS indeed. I use CMake and specify CMAKE_CUDA_STANDARD, which leads to an additional option being passed to nvcc -std=c++14. As you can see in the @fsb4000 example, there is no C++ standard version specified in the command line arguments (although it's mentioned in the project settings). When I check the __cplusplus variable its equal to 201402 for both cases.

@fsb4000
Copy link
Contributor

fsb4000 commented Jun 23, 2021

@senior-zero , @StephanTLavavej
Thanks, I also get the same error
CMakeLists.txt

cmake_minimum_required(VERSION 3.16)

if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
  set(CMAKE_CUDA_ARCHITECTURES 52)
endif()

project(cuda_testprj CUDA)

set(CMAKE_CUDA_STANDARD 14)

add_executable(untitled main.cu)

set_target_properties(
	untitled
	PROPERTIES
	CUDA_SEPARABLE_COMPILATION ON)
$ mkdir build
$ cd build
$ cmake -G Ninja -S .. -B ..\out  
$ ninja -C ..\out -v  
[1/3] C:\PROGRA~1\NVIDIA~2\CUDA\v11.3\bin\nvcc.exe -forward-unknown-to-host-compiler   -D_WINDOWS -Xcompiler=" /GR /EHsc" -Xcompiler="-Zi -Ob0 -Od /RTC1" --generate-code=arch=compute_52,code=[compute_52,sm_52] -Xcompiler=-MDd -std=c++14 -MD -MT CMakeFiles\untitled.dir\main.cu.obj -MF CMakeFiles\untitled.dir\main.cu.obj.d -x cu -dc ..\main.cu -o CMakeFiles\untitled.dir\main.cu.obj -Xcompiler=-FdCMakeFiles\untitled.dir\,-FS
FAILED: CMakeFiles/untitled.dir/main.cu.obj
...

I tried to build with same command but without -std=c++14 and it's worked.

When we change MSBuild C++ language to C++14, it does not add the flag to nvcc
изображение
If we add the flag ourself then we have the same error.
изображение
изображение

@fsb4000
Copy link
Contributor

fsb4000 commented Jun 23, 2021

cmake default generator also creates bad sln. (with -std=c++14)

$ cmake ..
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19043.
-- The CUDA compiler identification is NVIDIA 11.3.109
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Check for working CUDA compiler: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.3/bin/nvcc.exe - skipped
-- Detecting CUDA compile features
-- Detecting CUDA compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Dev/STL/playground/build

изображение

$ cmake --version
cmake version 3.20.2

CMake suite maintained and supported by Kitware (kitware.com/cmake).

@fsb4000
Copy link
Contributor

fsb4000 commented Jun 23, 2021

I found the same issue in the Devcom: https://developercommunity.visualstudio.com/t/VS-16100-isnt-compatible-with-CUDA-11/1433342

It marked as regression worked-in:16.9.

And https://developercommunity.visualstudio.com/t/MSVC-C142930037-with-CUDA-112-occur/1437930?space=62&sort=newest&stateGroup=closed&ftype=problem

nvcc 10.2 still works, but nvcc 11.2 does not.

Strange...

@StephanTLavavej
Copy link
Member

Thanks for finding the cause - we'll need to contact NVIDIA and ask them whether this is a regression that they can fix on their side.

@gevtushenko
Copy link
Author

I suppose we've found out that it's not STL related question, so I'm closing the issue. Thank you all!

@mszhanyi
Copy link

mszhanyi commented Nov 5, 2021

@senior-zero
In the same machine, Professional 16.9.2 works.
But There're exceptions with Enterprise 16.11.5

Enterprise\VC\Tools\MSVC\14.29.30133\include\xmemory(62): error: expected a "("
          detected during:
            instantiation of "size_t std::_Get_size_of_n<_Ty_size>(size_t) [with _Ty_size=4ULL]"
(839): here
            instantiation of "_Ty *std::allocator<_Ty>::allocate(size_t) [with _Ty=char32_t]"

@3a1b2c3
Copy link

3a1b2c3 commented Oct 20, 2022

did this get resolved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants