Как отключить определенные предупреждения компилятора nvcc

Я хочу отключить конкретное предупреждение компилятора с помощью nvcc, в частности

предупреждение: пустая ссылка не допускается

Код, над которым я работаю, использует ссылки NULL являются частью SFINAE, поэтому их нельзя избежать.

Идеальным решением была бы #pragma в исходном файле, где мы хотим отключить предупреждения, но флаг компилятора также подойдет, если он существует, чтобы отключить только рассматриваемое предупреждение.

Ответ 1

Фактически можно отключить определенные предупреждения на устройстве с помощью NVCC. Мне потребовались годы, чтобы понять, как это сделать.

Вам нужно использовать флаг -Xcudafe в сочетании с токеном, указанным на этой странице. Например, чтобы отключить предупреждение "контрольное выражение является постоянным", передайте в NVCC следующее:

-Xcudafe "--diag_suppress=boolean_controlling_expr_is_constant"

Другие предупреждения см. выше .

Ответ 2

Просто чтобы добавить к предыдущему ответу о -xcudafe (недостаточно репутации, чтобы оставить комментарий)

ОСНОВНЫЕ РЕДАКТИРОВАТЬ:

CudaFE - это, по-видимому, пользовательская версия Nvidia Front End от Edison Design Group. Вы можете найти документы для этого здесь: http://www.edg.com/docs/edg_cpp.pdf. В настоящее время я имею в виду номера страниц из справочника v5.1 за июль 2019 года.

@einpoklum отмечает, что просто выполнение push/pop, как я изначально говорил в первоначальном посте, не работает, и, в частности, что #pragma push генерирует предупреждение о том, что оно игнорируется. Я не мог воспроизвести предупреждение, но в тестовой программе, приведенной ниже, ни CUDA 10.1, ни CUDA 9.2 фактически ничего не делали в режиме push/pop (обратите внимание, что строки 20 и 22 не генерируют предупреждение).

Однако на странице 75 этого руководства рассказывается, как выполнить локализованный контроль серьезности диагностики без push/pop:

В следующем примере подавляется предупреждение "бессмысленное объявление друга" в объявлении класса 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; }

Ответ 3

Чтобы дополнить user2333829 ответ: если вы знаете имя предупреждения, вы можете отключить его следующим образом:

-Xcudafe "--diag_suppress=boolean_controlling_expr_is_constant"

Если вы не знаете имя, получите номера предупреждений, скомпилировав:

-Xcudafe --display_error_number

А затем с:

-Xcudafe --diag_suppress=<warning_number>

(Примечание: оба варианта одновременно не работают.)

Ответ 4

Я изо всех сил пытался найти соответствующий -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++.

введите описание изображения здесь

Ответ 5

Вы можете использовать флаг w для подавления предупреждений  nvcc -w

Ответ 6

Я использовал nvcc с компиляторами ubuntu g++, в моем случае openmpi mpic++. Для "-Wunused-result" компилятора g++ соответствующее подавление сообщения равно "-Wno-unused-result". Поэтому передача его в nvcc вроде -Xcompiler "-Wno-unused-result" сработала для меня.