Compiling .cu vs .cpp: Compiler errors even without any CUDA code

时间:2019-04-08 13:23:47

标签: c++ cuda nvcc

I compile the following code:

#include <iostream>
#include <boost/beast.hpp>


int main()
{
    std::cout << "Hello, world!\n";
}

via

$ 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
$ nvcc -O0 --std=c++14 -g -Xcompiler=-Wfatal-errors -I./include -I../boost  main.cu -o runserver

I get the compiler error:

boost/beast/core/impl/error.ipp(20): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::beast::detail::error_codes"

beast/core/impl/error.ipp(55): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::beast::detail::error_conditions"

boost/beast/core/impl/error.ipp(84): warning: invalid narrowing conversion from "unsigned int" to "int"

boost/beast/core/impl/error.ipp(92): warning: invalid narrowing conversion from "unsigned int" to "int"

boost/asio/impl/error.ipp(32): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::asio::error::detail::netdb_category"

boost/asio/impl/error.ipp(64): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::asio::error::detail::addrinfo_category"

boost/asio/impl/error.ipp(94): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::asio::error::detail::misc_category"

boost/beast/http/impl/error.ipp(21): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::beast::http::detail::http_error_category"

boost/beast/http/impl/error.ipp(96): warning: invalid narrowing conversion from "unsigned int" to "int"

boost/beast/websocket/impl/error.ipp(20): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::beast::websocket::detail::error_codes"

boost/beast/websocket/impl/error.ipp(117): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::beast::websocket::detail::error_conditions"

boost/beast/websocket/impl/error.ipp(144): warning: invalid narrowing conversion from "unsigned int" to "int"

boost/beast/websocket/impl/error.ipp(152): warning: invalid narrowing conversion from "unsigned int" to "int"

boost/beast/zlib/impl/error.ipp(49): warning: overloaded virtual function "boost::system::error_category::message" is only partially overridden in class "boost::beast::zlib::detail::error_codes"

boost/beast/zlib/impl/error.ipp(115): warning: invalid narrowing conversion from "unsigned int" to "int"

boost/beast/http/message.hpp(265): error: static assertion failed with "Fields type requirements not met"
          detected during:
            instantiation of class "boost::beast::http::header<false, Fields> [with Fields=boost::beast::http::fields]"
(495): here
            instantiation of class "boost::beast::http::message<isRequest, Body, Fields> [with isRequest=false, Body=boost::beast::http::string_body, Fields=boost::beast::http::fields]"
boost/beast/websocket/detail/impl_base.hpp(199): here

boost/beast/http/message.hpp(61): error: static assertion failed with "Fields type requirements not met"
          detected during:
            instantiation of class "boost::beast::http::header<true, Fields> [with Fields=boost::beast::http::fields]"
(495): here
            instantiation of class "boost::beast::http::message<isRequest, Body, Fields> [with isRequest=true, Body=boost::beast::http::empty_body, Fields=boost::beast::http::fields]"
boost/beast/websocket/detail/impl_base.hpp(257): here

2 errors detected in the compilation of "/tmp/tmpxft_00002a42_00000000-6_main.cpp1.ii".

However, if I change the file suffix to .cpp and compile with nvcc, no problems are encountered and everything is fine.

Why? I thought nvcc just forwarded CPU code to the host compiler.

In addition, it seems nvcc has a problem with the .ipp files. Is this a known problem?

1 个答案:

答案 0 :(得分:3)

Why? I thought nvcc just forwarded CPU code to the host compiler.

That is too simplistic a statement for understanding of what is happening here.

As you've discovered, nvcc behavior (by default) is different depending on whether the file extension is .cpp or .cu, even for purely host code.

A more complete description of the nvcc preprocessing associated with .cu files (even for host code) is given in the nvcc manual. An even more complete description can be obtained by running your nvcc command with --verbose switch; you can fully inspect the process in detail that way.

In a nutshell, host code in a .cu file goes through several preprocessing steps before it actually reaches the host C++ compiler. Host code in a .cpp file goes through fewer steps before reaching the host C++ compiler.

In addition, boost takes on specific behavior when it detects certain macros that the nvcc compiler adds to (even) host code, when that host code is in a .cu file. These macros, as detected by boost code, cause boost to "behave" differently. Here is an example.

I don't think there is any problem with .ipp files that are used in the conventional way. These are merely "add-ons" to header files, following the standard include mechanism. The fact that there are lot of .ipp files indicated in your error output is unrelated to this. It's merely a consequence of where the errors are occurring and how boost partitions its header code.

If you're actually looking to address this particular issue here, the usual suggestions are:

  1. Put your boost code in .cpp files (or)
  2. Use the latest versions of boost and CUDA (and)
  3. Report observed issues as either (or both) boost issues or bugs against CUDA at developer.nvidia.com (bug filing description is here)