У меня есть проект CUDA в файле .cu
, который я хотел бы скомпилировать в файл .mex
, используя mexcuda
. Поскольку в моем коде используется 64-разрядная атомарная операция с плавающей запятой atomicAdd(double *, double)
, которая предназначена только для устройств GPU с вычислительной мощностью 6.0 или выше, мне нужно указать это как флаг при компиляции.
В моей стандартной среде IDE это работает нормально, но при компиляции с mexcuda
это работает не так, как хотелось бы. В этой публикации на MathWorks было предложено использовать следующую команду (отредактировано из комментария Джосса Найта):
mexcuda('-v', 'mexGPUExample.cu', 'NVCCFLAGS=-gencode=arch=compute_60,code=sm_60')
, но когда я использую эту команду в своем файле, опция подробного вывода последней выводит следующую строку:
Building with 'NVIDIA CUDA Compiler'.
nvcc -c --compiler-options=/Zp8,/GR,/W3,/EHs,/nologo,/MD -
gencode=arch=compute_30,code=sm_30 -gencode=arch=compute_50,code=sm_50 -
gencode=arch=compute_60,code=sm_60 -
gencode=arch=compute_70,code=\"sm_70,compute_70\"
(и так далее), что сигнализирует мне, что указанный флаг не был передан в nvcc
должным образом. И действительно, компиляция не выполняется со следующей ошибкой:
C:/path/mexGPUExample.cu(35): error: no instance of overloaded function "atomicAdd" matches
the argument list. Argument types are: (double *, double)
Единственный другой пост по этой теме, который я смог найти, был этот пост о SO, но ему почти три года, и мне показалось, что он больше похож на обходной путь, который я не понимаю даже после некоторого исследования, иначе я бы попробовал это - а не верное решение проблемы.
Есть ли параметр, который я пропустил, или это просто невозможно сделать без обходного пути?
Связанный пост предназначен только для
mex
, а не дляmexcuda
. Кроме того, поскольку по умолчанию выполняется компиляция для всех архитектур, передать этот флаг не должно быть проблемой. Ошибка вызвана чем-то другим, а не отсутствием флагов.Можешь показать код? Ваша ошибка может быть вызвана неверным кодом
@AnderBiguri, вы получите эту ошибку, если скомпилируете с compute_30 и попытаетесь использовать double atomicAdd. Если вы используете в коде double atomicAdd, компилировать для всех архитектур - это не нормально. И это не значит, что это плохой код. Это означает, что вы не должны компилировать для compute_30, и OP спрашивает, как это сделать.
@RobertCrovella ну, это мог быть плохой код, но вы правы. Возможно, я просто не знаю достаточно, но можно предположить, что компиляция для всех архитектур означает, что генерируется код, который работает во всех архитектурах. Не больше ограничений, а меньше. Мое единственное предложение OP - использовать версию компиляции
mex
+xml
, а неmexcuda
. По моему опыту, с этим последним намного сложнее настроить параметры.в целом ваша интуиция верна. Но если вы используете определенную функцию, которая недоступна в более низкой архитектуре, вы не можете использовать эту архитектуру. Например, перемешивание деформации - это функция cc3.0. Вы не можете скомпилировать встроенные функции warp shuffle для цели cc2.0. Вы получите ошибку компиляции.
Аналогичным образом
double
atomicAdd
- это функция, для которой требуется cc6.0 или выше. Вы не можете скомпилировать его для архитектуры cc5.0 или ниже. если вы попытаетесь это сделать, даже если вы укажете несколько архитектур, вы получите ошибку компиляции. Следовательно, эти более низкие архитектуры должны быть удалены, что является сутью этого вопроса, поскольку он применяется к инструментальной цепочке mexcuda.Спасибо за комментарии, господа. Мне удалось найти обходной путь, изменив файл
xml
в папке MatLab, который я опубликую в качестве ответа для других. Это не изящно, но, по крайней мере, у меня работает. Я также рассмотрю предложениеmex
+xml
и отредактирую его в своем ответе, если найду что-нибудь, что работает. Я также посмотрю, смогу ли я уведомить кого-нибудь из MathWorks об этой «проблеме».@Ander, что касается вашего третьего комментария: вы правы в w.r.t. компиляция для всех архитектур. Компиляция для всех архитектур приведет к увеличению размера файла для файла функции
.mex
, потому что он будет содержать отдельный код для каждого и использовать соответствующий код в зависимости от архитектуры, из которой он был вызван, что обеспечивает лучшую переносимость. Моя скомпилированная функция не будет работать ни на одном графическом процессоре с более низкой вычислительной мощностью (по крайней мере, не должна ..)@RobertCrovella, это, безусловно, справедливое поведение. Спасибо, что научили нас (возможно, только меня), как обычно :)