20

我想用 禁用特定的编译器警告nvcc,特别是

警告:不允许 NULL 引用

我正在编写的代码使用NULL引用是 SFINAE 的一部分,因此无法避免。

一个理想的解决方案是#pragma在我们想要禁用警告的源文件中,但是如果存在一个编译器标志来只关闭有问题的警告,那么编译器标志也可以。

4

6 回答 6

28

实际上可以使用 NVCC 禁用设备上的特定警告。我花了很长时间才弄清楚该怎么做。

您需要将该标志与此页面-Xcudafe上列出的令牌结合使用。例如,要禁用“控制表达式是常量”警告,请将以下内容传递给 NVCC:

-Xcudafe "--diag_suppress=boolean_controlling_expr_is_constant"

有关其他警告,请参阅上面的链接

于 2013-06-13T19:59:40.153 回答
17

只是添加到关于 -xcudafe 的先前答案(还没有足够的声誉发表评论)

主要编辑:

cudaFE 显然是来自 Edison Design Group 的 Nvidia 定制版 C++ 前端。你可以在这里找到它的文档:http ://www.edg.com/docs/edg_cpp.pdf 。我目前指的是 2019 年 7 月 v5.1 手册中的页码。

@einpoklum 指出,像我最初在最初的帖子中所说的那样做 push/pop 是行不通的,特别是 #pragma push 会产生一个警告,表明它被忽略了。我无法复制警告,但实际上在下面的测试程序中,CUDA 10.1 和 CUDA 9.2 都没有推送/弹出实际上做任何事情(请注意,第 20 和 22 行不生成任何警告)。

但是,在本手册的第 75 页上,他们介绍了如何在没有推送/弹出的情况下进行本地化诊断严重性控制:

下面的例子抑制了 A 类声明中的“无意义的朋友声明”警告:

#pragma diag_suppress 522
class A { friend class A; };
#pragma diag_default 522
class B { friend class B; };

#pragma diag_default 将警告返回到默认状态。另一个例子是:

#pragma diag_suppress = code_is_unreachable
...
#pragma diag_default = code_is_unreachable

等号是可选的。测试表明这是可行的,并且真正本地化了严重性控制。此外,测试表明以这种方式添加诊断抑制会增加以前的诊断抑制 - 它不会取代。另外值得注意的是,在 CUDA 10.1 中,无法访问的代码在 CUDA 9.2 中没有生成警告。最后,手册的第 77 页提到了一种新的 push/pop 语法:

#pragma push_macro(“identifier”)
#pragma pop_macro(“identifier”)

但我无法让它在下面的程序中工作。

以上所有内容都在下面的程序中进行了测试,编译为nvcc -std=c++14 test_warning_suppression.cu -o test_warning_suppression

#include <cuda_runtime.h>

__host__ __device__ int return1(){
    int j = -1; //warning given for both CUDA 9.2 and 10.1
    return 1;
    if(false){ return 0; } //warning given here for CUDA 9.2
}

#pragma push
#pragma diag_suppress = code_is_unreachable 
#pragma diag_suppress = declared_but_not_referenced
__host__ __device__ int return2(){
    int j = -1;
    return 2;
    if(false){ return 0; }
}
#pragma pop

__host__ __device__ int return3(){
    int j = -1; //no warning given here
    return 3;
    if(false){ return 0; } //no warning here even in CUDA 9.2 
}

//push/pop did not localize warning suppression, so reset to default
#pragma diag_default = declared_but_not_referenced
#pragma diag_default = code_is_unreachable

//warning suppression localized to lines above by diag_default!
__host__ __device__ int return4(){
    int j = -1; //warning given for both CUDA 9.2 and 10.1
    return 4;
    if(false){ return 0; } //warning given here for CUDA 9.2
}

/* below does not work as of CUDA 10.1
#pragma push_macro(“identifier”)
#pragma diag_suppress = code_is_unreachable 
__device__ int return5(){
    return 5;
    if(false){ return 0; }
}
#pragma pop_macro(“identifier”)

__device__ int return6(){
    return 6;
    if(false){ return 0; }
} */

int main(){ return 0; }
于 2018-04-24T09:09:14.927 回答
9

要增加 user2333829 的答案:如果您知道警告名称,您可以像这样禁用它:

-Xcudafe "--diag_suppress=boolean_controlling_expr_is_constant"

如果您不知道名称,请通过编译获取警告编号:

-Xcudafe --display_error_number

然后:

-Xcudafe --diag_suppress=<warning_number>

(注意:两个选项同时显然不起作用。)

于 2019-01-11T08:39:10.320 回答
3

您可以使用 w 标志来抑制警告 nvcc -w

于 2018-02-13T04:53:14.497 回答
2

我努力-Xcudafe为我的警告找到匹配项。所以这里有另一种方式。

您可以将编译器标志传递给CL.exe它将禁用特定警告。例如,要禁用有关未经检查的迭代器的警告,您可以通过/wd4996.

warning C4996: 'std::_Copy_impl': Function call with parameters that may be
unsafe - this call relies on the caller to check that the passed values are 
correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See 
documentation on how to use Visual C++ 'Checked Iterators'

这里的棘手之处在于,默认情况下主机编译器设置中的参数不会传递给nvcc,因此您需要通过CUDA C/C++对话框添加它。

在此处输入图像描述

于 2017-02-18T21:31:28.327 回答
0

我将 nvcc 与 ubuntu g++ 编译器一起使用,在我的例子中是 openmpi mpic++。对于 g++ 编译器的“-Wunused-result”,相应的消息抑制是“-Wno-unused-result”。所以像 -Xcompiler "-Wno-unused-result" 这样在 nvcc 中传递它对我有用。

于 2019-05-10T19:41:44.067 回答