Как отключить определенные предупреждения компилятора 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" сработала для меня.