21

I want to disable a specific compiler warning with nvcc, specifically

warning: NULL reference is not allowed

The code I am working on uses NULL references are part of SFINAE, so they can't be avoided.

An ideal solution would be a #pragma in just the source file where we want to disable the warnings, but a compiler flag would also be fine, if one exists to turn off only the warning in question.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
bcumming
  • 1,075
  • 2
  • 8
  • 17
  • you can `google` that, or read `nvcc` manual. – Soroosh Bateni Feb 12 '13 at 11:15
  • 2
    by typing `nvcc --help` I can see that there is a `--disable-warnings` option or equally `-w`. – Soroosh Bateni Feb 12 '13 at 11:18
  • thanks @Soroosh129. I will edit my question to be more specific: I want something with more fine-grained control than just turning off all warning messages, because warnings are a good thing! Unfortunately I have not been able to find this by using google, or by looking up the manual. – bcumming Feb 12 '13 at 12:30
  • 1
    Are the warnings coming from host or device code (remember, nvcc isn't a compiler..)? – talonmies Feb 12 '13 at 12:52
  • @talonmies.. then what is nvcc? – sgarizvi Feb 12 '13 at 12:54
  • @bcumming to do fine-grained control, develop a script bypassing desired warnings and prompting the other. Name the script as `nvcc` and put it in the PATH just ahead of real nvcc. – lashgar Feb 12 '13 at 13:04
  • 3
    @sgar91: It is a *compiler driver*. The warnings either come from the host compiler (microsoft c++ or gcc) or the device compiler (llvm or open64 depending on what architecture you compile for). Which is why I asked about whether the warnings are in device or host code. – talonmies Feb 12 '13 at 13:34
  • @talonmies: it is in the device code. The warnings are not generated by gcc nor msvc++, because when the same code is compiled on Windows and Linux using those compilers, we get no warnings. So the question might be: is it possible to pass flags to compilers used at specific stages of the compilation process by nvcc? – bcumming Feb 12 '13 at 15:33
  • Are you using the templates in device code? If not, you may want to move your templates out of the `.cu` files. CUDA C is close to, but not completely compatible with, C++. You may run into other issues when trying to use more obscure C++ features. The `.cu` files can also be rather slow to compile, so it can be an advantage in the long run to keep only device code in them. – Roger Dahl Feb 12 '13 at 17:12
  • We are implementing an embedded DSL in C++, with OpenMP and CUDA backends, so the templates have to be in the .cu files (in fact, the .cu files simply `#include "file.cpp"`). We are also well-aware of the limitations of templates in CUDA! – bcumming Feb 13 '13 at 08:04

7 Answers7

29

It is actually possible to disable specific warnings on the device with NVCC. It took me ages to figure out how to do it.

You need to use the -Xcudafe flag combined with a token listed on this page. For example, to disable the "controlling expression is constant" warning, pass the following to NVCC:

-Xcudafe "--diag_suppress=boolean_controlling_expr_is_constant"

For other warnings, see the above link.

janisz
  • 6,292
  • 4
  • 37
  • 70
user2333829
  • 1,301
  • 1
  • 15
  • 25
  • I am not able to set this up with Visual Studio 2012 and CUDA 5.5. With 4.2 and an older Studio it worked. Btw there was a discussion about this issue (with the same conclusion as here) on devtalk.nvidia.com. See: https://devtalk.nvidia.com/default/topic/370952/disable-a-warning-/ – hthms Mar 26 '14 at 13:30
  • @user2333829: cudafe excepts several (many?) other tokens than the ones on the list you mentioned, plus I'm not sure it will actually accept everything on that list. Have you tried most of them? – einpoklum Apr 11 '14 at 16:26
  • This answer is godsend if you include a library like Eigen because the controlling expression warning spam makes it effectively impossible to see any other warning. – Mranz Jun 29 '14 at 18:12
  • is there any way to do this more locally with a pragma? – Joe Apr 04 '16 at 11:19
  • A list of possibilities for diag_suppress are here: http://www.ssl.berkeley.edu/~jimm/grizzly_docs/SSL/opt/intel/cc/9.0/lib/locale/en_US/mcpcom.msg – Aaron Swan Aug 03 '18 at 21:47
  • 3
    Also found that you can add "-Xcudafe --display_error_number" to the nvcc command to produce an error number. The number (excluding any symbols or letters) can be used as the argument to diag_suppress (e.g. in a file: #pragma diag_suppress 2381). – Aaron Swan Aug 03 '18 at 22:11
  • What's the syntax if we want to disable multiple warnings? – étale-cohomology Oct 16 '19 at 12:40
  • After trying this approach and the warning recurring on different machines, I investigated and the numbers vary between platforms and minor CUDA versions. HOWEVER, the string tokens can be found quite easily by dumping the symbols from cudafe++ :D – neworderofjamie Sep 29 '20 at 09:42
17

Just to add to the previous answer about -xcudafe (not enough reputation yet to leave a comment)

MAJOR EDIT:

cudaFE is apparently Nvidia's custom version of C++ Front End from the Edison Design Group. You can find the docs for it here: http://www.edg.com/docs/edg_cpp.pdf. I am currently referring to page numbers from the July 2019 v5.1 manual.

@einpoklum notes that just doing push/pop as I had originally stated in the initial post doesn't work and specifically that #pragma push generates a warning that it is ignored. I could not replicate the warning, but indeed in the test program below neither CUDA 10.1 nor CUDA 9.2 did the push/pop actually do anything (note that lines 20 and 22 generate no warning).

However, on page 75 of this manual they go through how to do localized diagnostic severity control without push/pop:

The following example suppresses the “pointless friend declaration” warning on the declaration of class A:

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

The #pragma diag_default returns the warning to default state. Another example would be:

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

The equal symbol is optional. Testing shows that this works and truly localized the severity control. Further, testing reveals that adding diagnostic suppressions in this way adds to previous diagnostic suppressions - it doesn’t replace. Also of note, in CUDA 10.1 unreachable code did not generate a warning while it did in CUDA 9.2. Finally, Page 77 of the manual mentions a new push/pop syntax:

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

But I couldn't get it to work in the program below.

All of the above is tested in the program below, compiled with 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; }
dada_dave
  • 493
  • 4
  • 13
  • Thanks for the solution. It is perfect for targeting just the lines of code in question. I have referenced you in an edit to my question. I discovered that nvcc uses the Edison Design Group front end when I noticed that both the Intel compiler and nvcc have the same front end compiler bugs! – bcumming Apr 26 '18 at 20:10
  • my pleasure! it took awhile to figure this out, so I thought I'd share – dada_dave May 01 '18 at 00:24
  • 2
    A list of possibilities for diag_suppress are here: http://www.ssl.berkeley.edu/~jimm/grizzly_docs/SSL/opt/intel/cc/9.0/lib/locale/en_US/mcpcom.msg – Aaron Swan Aug 03 '18 at 21:46
  • 1
    Does this pragma _add_ to the suppressions in the surrounding environment, or does it _replace_ the suppressions? – einpoklum May 13 '19 at 19:40
  • 1
    Anyway, If I do this, I get complaints about the push and the pop: `warning: ignoring #pragma push` etc. – einpoklum May 17 '19 at 20:03
  • @einpoklum Looking at the user manual, it appears that the syntax for push/pop has changed (page 77). On page 75 they go through how to do it without using push/pop at all - either way should just be adding suppressions rather than suppressing them, but I've been so swamped with work, I haven't time to test. I'll edit my answer above to reflect the new syntax. Thanks for bringing it to my attention! – dada_dave May 18 '19 at 21:11
  • @einpoklum So I finally tested this - I couldn't regenerate einpoklum's warning, but indeed push/pop did not properly localize the warning suppression (see line 28 of program above). I had to set diagnostic to default instead (see my example program). Also, I tested that indeed adding diag_suppress adds, not replaces suppressions. Thank you for catching this. – dada_dave Jul 20 '19 at 01:53
  • @Robert Crovella While I couldn't generate a warning message, push/pop did not seem to properly localize warning suppressions. – dada_dave Jul 20 '19 at 01:54
9

To augment user2333829's answer: if you know the warning name you can disable it like this:

-Xcudafe "--diag_suppress=boolean_controlling_expr_is_constant"

If you don't know the name, get warning numbers by compiling with:

-Xcudafe --display_error_number

And then with:

-Xcudafe --diag_suppress=<warning_number>

(Note: both options at the same time apparently don't work.)

Zbyl
  • 2,130
  • 1
  • 17
  • 26
  • 1
    Both options at the same time work, but require some extra care. Either `-Xcudafe --display_error_number -Xcudafe --diag_suppress=` or `-Xcudafe "--display_error_number --diag_suppress="`. – Jakub Klinkovský Feb 10 '19 at 09:39
  • What if the warning "number" you get isn't a number, but a string, e.g. `#20208-D`? What do you use for suppression? – einpoklum Jun 17 '21 at 20:23
  • ... ok, it seems you just use the number and it works. But - what do you use for suppression using `#pragma diag_suppress"` ? – einpoklum Jun 17 '21 at 20:43
3

You can use w flag to suppress the warnings nvcc -w

Kavindra
  • 1,697
  • 2
  • 14
  • 19
2

I struggled to find a matching -Xcudafe for my warning. So here is another way.

You can pass a compiler flag to CL.exe that will disable a specific warning. For example, to disable the warnings about unchecked iterators you can pass /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'

The tricky thing here is that by default the arguments from the host compiler settings are not passed to nvcc, so you need to add it via the CUDA C/C++ dialog.

enter image description here

Mikhail
  • 7,749
  • 11
  • 62
  • 136
0

I was using nvcc with the ubuntu g++ compilers, in my case openmpi mpic++. For the "-Wunused-result" of the g++ compiler the corresponding message suppress is "-Wno-unused-result". So passing it in the nvcc like -Xcompiler "-Wno-unused-result" worked for me.