Ошибки компиляции nvcc с "M_PI" и "or" - PullRequest
0 голосов
/ 27 мая 2019

При попытке скомпилировать этот фрагмент кода:

#define _USE_MATH_DEFINES
#include <cmath>
#include <cstdio>

void minimal_example(){
    int i=2;
    if(i==3 or i==4) printf("I want %d!\n",M_PI);
}

с помощью

nvcc -x cu -Xcompiler=/permissive- -dc cuda_nvcc_cl_test.cu -o cuda_nvcc_cl_test.obj

Я получаю следующие ошибки (в строке 7):

error: expected a ")"
error: identifier "M_PI" is undefined

Я использую Windows 10 с cl.exe для Visual Studio (версия 19.16.27031.1 для x64) и инструментарий CUDA 10.1.

При замене cmath на math.h и or на || (альтернативно добавьте #include <ciso646>), ошибки исчезают. Однако, есть ли какие-то опции компилятора или другие возможности, чтобы я мог сохранить код как есть?

Также, почему -Xcompiler=/permissive- не помог?

1 Ответ

2 голосов
/ 29 мая 2019

Здесь есть 2 проблемы:

  1. Очевидно, nvcc включает cmath до анализа вашего кода.Как обсуждалось в принятом ответе здесь , если вы включите cmath и у вас нет определения, определенного в этой точке, вы не получите M_PI определено, и последующие включения cmath не исправят это из-за включения охраны.Возможный обходной путь для этого - добавить -D_USE_MATH_DEFINES в командную строку компиляции.Это ставит определение на месте с начала процесса компиляции, и M_PI определяется таким образом.

  2. Вопреки тому, что я прочитал как правильное или стандартное поведение, использование or вместо ||, кажется, обусловлено включением ciso646 (на nvcc только для windows / visual studio. nvcc на linux, похоже, не нуждается в этом).Да, я понимаю, что это не должно работать, но, тем не менее, это необходимо. Это может быть проблема с Visual Studio .Вы можете поэкспериментировать с переключателем /Za, если хотите.(Похоже, это не помогло, когда я попробовал.)

С CUDA 10.1, на VS2019, когда я компилирую это:

#include <cstdio>
#include <ciso646>

void minimal_example(){
    int i=2;
    if(i==3 or i==4) printf("I want %f!\n",M_PI);
}

с этой командойстрока:

nvcc -x cu -dc test.cu -o test.obj -D_USE_MATH_DEFINES

Я не получаю ошибок или предупреждений.Обратите внимание, что я также изменил ваш спецификатор формата printf с %d на %f, чтобы он соответствовал типу M_PI.

Если вы действительно не хотите включать ciso646,nvcc поддерживает переключатель -include для включения файла непосредственно из командной строки.Поэтому я могу скомпилировать это:

#include <cstdio>

void minimal_example(){
    int i=2;
    if(i==3 or i==4) printf("I want %f!\n",M_PI);
}

следующим образом:

nvcc -x cu -dc test.cu -o test.obj -D_USE_MATH_DEFINES -include ciso646

без ошибок или предупреждений.

...