Компиляция кода CUDA в Linux, но не в Windows (Visual Studio 2012) - PullRequest
0 голосов
/ 10 июля 2019

Я занимаюсь разработкой программы, которая использует набор инструментов для разработки CUDA версии 10.1, и я использую Visual Studio 2012. Я работаю над Windows, но делюсь кодом с пользователем Linux.Весь код прекрасно работает в двух случаях, за исключением некоторой строки кода, которая работает в Linux, но не в Windows.Поэтому каждый раз мне приходится менять эти строки.Я бы избегал этого, и из-за того, что в Linux код компилируется хорошо, я думаю, что есть некоторые причины, по которым в Windows не компилируется, но эти причины должны быть точно не в коде, а в некоторых настройках Visual Studio илианалогичный.Вы можете мне помочь?В частности, строка кодов:

int n_devices = 0;
cudaGetDeviceCount(&n_devices);
cudaDeviceProp props[n_devices];

В последней строке у меня есть ошибка:

ошибка: выражение должно иметь постоянное значение

Я могу исправить эту ошибку, задав const int n_devices = 1; и комментируя функцию cudaGetDeviceCount(&n_devices);.Это работает, потому что я уже знаю правильное количество устройств, но наверняка это менее правильное решение, чем предыдущее.

Другая проблема заключается в том, что у меня есть файл utils.cuh, в котором определены два значения const

const float PI = 3.141592654f;
const float EPS = 1e-3f;

Я вызываю эти два значения в файле utils.cu, и во время компиляции у меня появляется ошибка:

ошибка: "PI" не определен в коде устройства

ошибка: «EPS» не определена в коде устройства

Я могу исправить это, объявив эти две переменные следующим образом:

#define PI 3.141592654f
#define EPS 1e-3f

Так что, даже если я могу исправить вседве проблемы, которые я действительно хочу оставить код в первой конфигурации (так как он работает на Linux).Может ли быть проблема, связанная с версией компилятора?Я действительно не знаю, в чем может быть причина.

1 Ответ

2 голосов
/ 10 июля 2019

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

Первая проблема описана здесь и здесь , это не имеет ничего общего с CUDA, за исключением того, что CUDA использует компилятор хоста.Код, который вы показали, использует VLA (массив переменной длины), который является частью стандарта C99, но не является частью какого-либо стандарта C ++.CUDA в основном реализован на основе C ++ и использует компилятор хоста C ++ для компиляции кода хоста, что вы и показали.В Windows для этого используется компилятор Microsoft.Таким образом, компилятор Microsoft является правильным, чтобы запретить VLA, и нет никакого способа избежать этого AFAIK.Ваш код работает в linux, потому что в linux nvcc используется хост-компилятор g++, и он позволяет (нестандартным образом) использовать VLA в хост-коде C ++.

Я не знаю ни одного метода для решения этой проблемы, который не подразумевал бы некоторые изменения в вашем коде для кросс-платформенной совместимости.Но небольшое количество навыков программирования (C или) C ++ может предоставить вам решение, которое должно работать на Linux или Windows:

int n_devices = 0;
cudaGetDeviceCount(&n_devices);
cudaDeviceProp *props = new cudaDeviceProp[n_devices];

(если вы хотите использовать метод, совместимый с C, вы можете использоватьmalloc аналогичным образом)

Вторая проблема связана с ограничением CUDA, здесь задокументировано здесь .

Нет также способа для решения этой проблемы.Платформа, о которой я знаю, не требует никаких изменений в вашем коде.

Вы уже определили один возможный обходной путь, который может работать кросс-платформенным способом как в Linux, так и в Windows:

#define PI 3.141592654f
#define EPS 1e-3f
...